Як зробити автоматичне збільшення первинного ключа таблиці MySQL з деяким префіксом


80

У мене такий стіл

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

Я хочу збільшити своє поле ідентифікатора, як 'LHPL001','LHPL002','LHPL003'... тощо. Що я повинен зробити для цього? Будь ласка, повідомте мені будь-який можливий спосіб.


просто додайте ще один стовпець, щоб зробити це. цілком нормально мати в базі даних "різні види" полів ідентифікатора.
Fattie

Відповіді:


135

Якщо вам це дійсно потрібно, ви можете досягти своєї мети за допомогою окремої таблиці для послідовності (якщо ви не проти) та тригера.

Столи

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)
);

Тепер тригер

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 ;

Потім ви просто вставляєте рядки в таблицю1

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

І ти матимеш

| Посвідчення особи | НАЗВА |
------------------
| LHPL001 | Джон |
| LHPL002 | Позначити |

Ось демонстрація SQLFiddle


Чи є заява всередині тригера атомною? Тобто чи можливо, що між INSERT та SET інший потік / запит вставляється в table1_seq, викликаючи LAST_INSERT_ID (), щоб повернути ідентифікатор іншого запиту, а не того, який був вставлений в BEGIN / END.
n00b

@peterm, у мене є сумнівна тригерна частина. Я змінив SET NEW.id = CONCAT ('A', LPAD (LAST_INSERT_ID (), 4, '500')); тому що мені потрібен мій ідентифікатор, починаючи з 5001, тому я встановив 500. Отже, я отримую вихід A5001, який є правильним. Я сумніваюся, що коли ідентифікатор досягне 5999, то яким буде наступний ідентифікатор? Це 6000?
user9437856

Я спробував самостійно після додавання записів у базу даних, додав більше 1000 записів, а після 5999 моє значення id починається з V1000, що є абсолютно неправильним. Мені потрібно, щоб це було продовжено 6000 6001 6002 і так далі. будь-яка ідея в цьому?
користувач9437856

18

Створіть таблицю із звичайним числовим ідентифікатором auto_increment, але або визначте її за допомогою ZEROFILL, або використовуйте LPADдля додавання нулів при виборі. Потім CONCATзначення, щоб отримати бажану поведінку. Приклад №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 |
+---------+------+

Приклад №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 |
+---------+------+

Спочатку я думав зберегти LHPL як окремий стовпець, потім зв'язати його за допомогою concat (col1, col2), але тоді це буде біль у S, коли одного дня мені потрібно буде змінити LHPL. Отже, я думаю, я буду робити це на стороні програмного сервера.
4 Залиште обкладинку

3

Я знаю, що пізно, але я просто хочу поділитися тим, що я зробив для цього. Мені не дозволено додавати іншу таблицю або тригер, тому мені потрібно його генерувати в одному запиті після вставки. Ви можете спробувати цей запит для свого випадку.

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

Виконайте вибір і скористайтеся цим запитом вибору та збережіть у параметрі @IDNUMBER

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

І тоді запит Вставити буде:

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

Результат буде однаковим з іншою відповіддю, але різниця полягає в тому, що вам не потрібно буде створювати іншу таблицю або тригер. Я сподіваюся, що можу допомогти комусь, хто має такий самий випадок, як і я.


0

Ось приклад PostgreSQL без тригера, якщо комусь він потрібен на 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.