Mysql 触发器在创建记录时将 id 从一列复制到另一列 table
Mysql trigger to copy id from one column to another in same table when record is created
创建新记录时,我需要将 id 字段从一列复制到另一列。两列中的数字必须相同,在最好的情况下,它应该在同一时刻插入到数据库中。我发现的最佳解决方案可能是使用触发器。
我这样创建 sql:
TRIGGER `db`.`copy_id_into_mbc_id` BEFORE INSERT ON `my_table` FOR EACH ROW
BEGIN
SET NEW.mbc_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES where TABLE_SCHEMA='mbc' and TABLE_NAME='my_table');
END
这个解决方案似乎有效,但我需要知道它是否安全。我读了一些旧话题,因为有些人说它会导致竞争条件。我不确定在哪种情况下这是有风险的,因为从我的测试来看它似乎很好。
有没有更好的方法来确保插入时两列的值完全相同? Id 字段是自动递增的,在代码中我不知道它,直到创建记录,但此时更新第二个字段对我来说已经晚了。
所以我的问题是:当创建新记录时,两列中的这个触发器值将始终相同吗?在 mysql 5.5 或 doctrine/php 中是否有更好的方法来保持两个值相同?
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, val INT);
CREATE TRIGGER tr
BEFORE INSERT
ON test
FOR EACH ROW
SET NEW.val = ( SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE()
AND TABLE_NAME='test' );
INSERT INTO test (id)
SELECT NULL UNION ALL SELECT NULL;
SELECT * FROM test;
id | val
-: | --:
1 | 1
2 | 1
db<>fiddle here
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, val INT);
CREATE TRIGGER tr
BEFORE INSERT
ON test
FOR EACH ROW
SET NEW.val = ( SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA=DATABASE()
AND TABLE_NAME='test' );
CREATE PROCEDURE fill ()
BEGIN
DECLARE cnt INT DEFAULT 0;
WHILE cnt < 2 DO
INSERT INTO test (id) VALUES (NULL);
SET cnt := cnt + 1;
END WHILE;
END;;
CALL fill();
SELECT * FROM test;
id | val
-: | --:
1 | 1
2 | 1
db<>fiddle here
创建新记录时,我需要将 id 字段从一列复制到另一列。两列中的数字必须相同,在最好的情况下,它应该在同一时刻插入到数据库中。我发现的最佳解决方案可能是使用触发器。
我这样创建 sql:
TRIGGER `db`.`copy_id_into_mbc_id` BEFORE INSERT ON `my_table` FOR EACH ROW
BEGIN
SET NEW.mbc_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES where TABLE_SCHEMA='mbc' and TABLE_NAME='my_table');
END
这个解决方案似乎有效,但我需要知道它是否安全。我读了一些旧话题,因为有些人说它会导致竞争条件。我不确定在哪种情况下这是有风险的,因为从我的测试来看它似乎很好。
有没有更好的方法来确保插入时两列的值完全相同? Id 字段是自动递增的,在代码中我不知道它,直到创建记录,但此时更新第二个字段对我来说已经晚了。
所以我的问题是:当创建新记录时,两列中的这个触发器值将始终相同吗?在 mysql 5.5 或 doctrine/php 中是否有更好的方法来保持两个值相同?
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, val INT);
CREATE TRIGGER tr BEFORE INSERT ON test FOR EACH ROW SET NEW.val = ( SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='test' );
INSERT INTO test (id) SELECT NULL UNION ALL SELECT NULL; SELECT * FROM test;
id | val -: | --: 1 | 1 2 | 1
db<>fiddle here
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, val INT);
CREATE TRIGGER tr BEFORE INSERT ON test FOR EACH ROW SET NEW.val = ( SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='test' );
CREATE PROCEDURE fill () BEGIN DECLARE cnt INT DEFAULT 0; WHILE cnt < 2 DO INSERT INTO test (id) VALUES (NULL); SET cnt := cnt + 1; END WHILE; END;;
CALL fill(); SELECT * FROM test;
id | val -: | --: 1 | 1 2 | 1
db<>fiddle here