Cómo hacer que la clave principal de la tabla MySQL se incremente automáticamente con algún prefijo

80

Tengo mesa como esta

table
id Varchar(45) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name CHAR(30) NOT NULL,

Quiero incrementar mi campo de identificación como 'LHPL001','LHPL002','LHPL003'... etc. ¿Qué debo hacer para eso? Por favor avíseme de cualquier manera posible.

Vijay
fuente
simplemente agregue otra columna para hacer esto. es totalmente normal tener "diferentes tipos" de campos de identificación en una base de datos.
Fattie

Respuestas:

135

Si realmente lo necesita, puede lograr su objetivo con la ayuda de una tabla separada para la secuenciación (si no le importa) y un disparador.

Mesas

CREATE TABLE table1_seq
(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE table1
(
  id VARCHAR(7) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);

Ahora el gatillo

DELIMITER $$
CREATE TRIGGER tg_table1_insert
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
  INSERT INTO table1_seq VALUES (NULL);
  SET NEW.id = CONCAT('LHPL', LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;

Luego, simplemente inserta filas en la tabla1

INSERT INTO Table1 (name) 
VALUES ('Jhon'), ('Mark');

Y tendrás

| ID | NOMBRE |
------------------
| LHPL001 | Jhon |
| LHPL002 | Mark |

Aquí está la demostración de SQLFiddle

peterm
fuente
¿La declaración dentro del disparador es atómica? Es decir, es posible que entre INSERT y SET otro hilo / solicitud se inserte en table1_seq haciendo que LAST_INSERT_ID () devuelva el id de la otra solicitud y no el que se insertó dentro de BEGIN / END.
n00b
@peterm, tengo una duda sobre la parte desencadenante. Cambié SET NEW.id = CONCAT ('A', LPAD (LAST_INSERT_ID (), 4, '500')); porque necesito que mi identificación comience desde 5001, así que configuré 500. Entonces obtengo la salida A5001, que es correcta. Mi duda es que una vez que la identificación llegue a 5999, ¿cuál será la siguiente identificación? ¿Son 6000?
user9437856
Lo intenté por mí mismo después de agregar los registros en la base de datos, agregué más de 1000 registros y después de 5999 mi valor de identificación comienza desde V1000, lo cual es totalmente incorrecto. Necesito que se continúe 6000,6001,6002 y así sucesivamente. alguna idea en esto?
user9437856
18

Cree una tabla con un ID de auto_increment numérico normal, pero defínalo con ZEROFILLo utilícelo LPADpara agregar ceros al seleccionar. Luego, CONCATlos valores para obtener su comportamiento previsto. Ejemplo 1:

create table so (
 id int(3) unsigned zerofill not null auto_increment primary key,
 name varchar(30) not null
);

insert into so set name = 'John';
insert into so set name = 'Mark';

select concat('LHPL', id) as id, name from so;
+---------+------+
| id      | name |
+---------+------+
| LHPL001 | John |
| LHPL002 | Mark |
+---------+------+

Ejemplo # 2:

create table so (
 id int unsigned not null auto_increment primary key,
 name varchar(30) not null
);

insert into so set name = 'John';
insert into so set name = 'Mark';

select concat('LHPL', LPAD(id, 3, 0)) as id, name from so;
+---------+------+
| id      | name |
+---------+------+
| LHPL001 | John |
| LHPL002 | Mark |
+---------+------+
Mullido
fuente
Inicialmente, estaba pensando en almacenar el LHPL como una columna separada y luego concatizarlo por concat (col1, col2) pero luego será un dolor de cabeza cuando algún día necesite cambiar el LHPL. Así que supongo que lo haré en el servidor del programa.
4 Deja la portada
3

Sé que es tarde, pero solo quiero compartir lo que he hecho al respecto. No puedo agregar otra tabla o activador, por lo que necesito generarlo en una sola consulta al insertarlo. Para su caso, ¿puede probar esta consulta?

CREATE TABLE YOURTABLE(
IDNUMBER VARCHAR(7) NOT NULL PRIMARY KEY,
ENAME VARCHAR(30) not null
);

Realice una selección y use esta consulta de selección y guárdela en el parámetro @IDNUMBER

(SELECT IFNULL
     (CONCAT('LHPL',LPAD(
       (SUBSTRING_INDEX
        (MAX(`IDNUMBER`), 'LHPL',-1) + 1), 5, '0')), 'LHPL001')
    AS 'IDNUMBER' FROM YOURTABLE ORDER BY `IDNUMBER` ASC)

Y luego Insertar consulta será:

INSERT INTO YOURTABLE(IDNUMBER, ENAME) VALUES 
(@IDNUMBER, 'EMPLOYEE NAME');

El resultado será el mismo que el de la otra respuesta, pero la diferencia es que no necesitará crear otra tabla o activador. Espero poder ayudar a alguien que tenga el mismo caso que el mío.

yhAm
fuente
0

Aquí hay un ejemplo de PostgreSQL sin disparador si alguien lo necesita en PostgreSQL:

CREATE SEQUENCE messages_seq;

 CREATE TABLE IF NOT EXISTS messages (
    id CHAR(20) NOT NULL DEFAULT ('message_' || nextval('messages_seq')),
    name CHAR(30) NOT NULL,
);

ALTER SEQUENCE messages_seq OWNED BY messages.id;
Ildar Nasurlaev
fuente