Mysql

需要在觸發器內部更改自動增量值

  • September 8, 2017

我已經轉換的表有一個小問題,它曾經是 MyISAM,我現在把它變成了 InnoDB 表。

原始結構:

id varchar(15),
seqno int(11) auto increment 
Joint PK index on the above 2 fields

新結構:

auto_id INT (11) auto increment,
id varchar(15),
seqno int(11)

原始結構在 id 和 seqno 上有一個聯合 PK,其中 seqno 會針對每個唯一的 id 值自動遞增。然後它將 seqno 作為我的 Web 應用程序中的 last_insert_id 返回。

使用新的 innodb 結構,因為 innodb 不支持聯合主鍵,我不得不添加一個 auto_id,它現在具有自動增量。

然後我實現了一個觸發器來生成每個 id 值唯一的 seqno。我的問題是如何設置自動增量 id 以便它返回代替 auto_id 值?當我插入 my_table 時會呼叫此觸發器,以便它可以計算下一個要插入的 seqno 值。

DROP TRIGGER IF EXISTS `innodb_seqno_trigger`;
//

CREATE TRIGGER `innodb_seqno_trigger` BEFORE INSERT ON `my_table`
FOR EACH ROW BEGIN

SET @newseqno = 0;

SELECT MAX(seqno) INTO @newseqno
FROM my_table
WHERE id = NEW.id;

SET NEW.seqno = (@newseqno + 1);
/* HERE I NEED HELP PLEASE TO GET THE AUTO INCREMENT VALUE TO ACTUALLY RETURN NEW.seqno */
END;
//

謝謝彼得

我認為您無法auto_idBEFORE插入觸發器中獲得新值。這將做你想要的(如果我理解正確的話):

CREATE TRIGGER innodb_seqno_trigger 
  BEFORE INSERT ON my_table 
  FOR EACH ROW 
BEGIN

 SELECT MAX(seqno) INTO @newseqno 
 FROM my_table 
 WHERE id = NEW.id;

 SET NEW.seqno = COALESCE(@newseqno + 1, 1); 

END; 

在**SQL-Fiddle進行測試**

但是您是否想過如果您有 2 個單獨的連接/執行緒/事務嘗試插入相同的內容會發生什麼id

因為innodb不支持聯合主鍵

等等,什麼?

除非“聯合主鍵”將組合鍵或複合鍵以外的其他內容描述為主鍵,否則當然InnoDB支持這一點。

mysql> CREATE TABLE `jpk` (
 `id` varchar(15) NOT NULL,
 `seqno` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`,`seqno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ERROR 1075 (42000): Incorrect table definition; there can be only one 
auto column and it must be defined as a key

好吧,好吧……不是 InnoDB 不允許,只是auto_increment列必須聲明為鍵(索引)……所以,將 seqno 設為鍵,InnoDB 沒有問題:

mysql> CREATE TABLE `jpk` (
 `id` varchar(15) NOT NULL,
 `seqno` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`,`seqno`),
 KEY `seqno` (`seqno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Query OK, 0 rows affected (0.25 sec)

還是我錯過了什麼?

引用自:https://dba.stackexchange.com/questions/45567