我需要在插入时将 auto_increment ID 值复制到另一列中。我想我需要一个“插入后”触发器,因为否则新 ID 是未知的..?
我试过这个:
IF NEW.content IS NULL THEN
SET NEW.content = NEW.id;
END IF
但它抱怨:
触发器后不允许更新新行
在这段代码上
CREATE TRIGGER insert_example
BEFORE INSERT ON notes
FOR EACH ROW
SET NEW.content = (
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'notes'
);
我做了这样的事情
SET NEW.content = (SELECT CONCAT('ID',LPAD(AUTO_INCREMENT, number,'0'))
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'notes');
如果您在 id 字段上使用 UNSIGNED_ZEROFILL ...并且您可能需要自定义类型的“公共”ID ...
正如 OP 所指出的,NEW.id 不适用于自动增量;可以使用以下触发器(使用风险自负)。尝试这个。
CREATE TRIGGER insert_example
BEFORE INSERT ON notes
FOR EACH ROW
SET NEW.content = (
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'notes'
);
如果您出于某种原因确实需要此行为,您可以通过使用单独的表进行排序和BEFORE INSERT
触发器来实现它
首先,您需要一个用于排序目的的简单表,它可能看起来像
CREATE TABLE table1_seq
(
id int not null auto_increment primary key
);
那么您的事实表架构可能看起来像
CREATE TABLE table1
(
id int not null default 0 primary key,
content int
);
现在触发
DELIMITER $$
CREATE TRIGGER tg_ai_table1
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO table1_seq() VALUES();
SET NEW.id = LAST_INSERT_ID(), NEW.content = COALESCE(NEW.content, NEW.id);
END$$
DELIMITER ;
现在你如果你插入table1
INSERT INTO table1 () VALUES (NULL),(-1);
你会有
| 身份证 | 内容 | |----|---------| | 1 | 1 | | 2 | -1 |
这是SQLFiddle演示
有点麻烦,你能不能说
DELIMITER $$
CREATE TRIGGER sometrigger
AFTER INSERT ON sometable
BEGIN
UPDATE sometable SET content = NEW.id WHERE id = NEW.id;
END $$
通过完整查询更新(相同)表,而不是尝试使用 SET。
甚至
DELIMITER $$
CREATE TRIGGER sometrigger
AFTER INSERT ON sometable
BEGIN
UPDATE sometable SET content = id WHERE content is null;
END $$
(这有点类似于 Allita 对事件的建议)
是的,这对于触发器是不可能的。你能做的最好的就是INSERT
用 a 替换语句CALL some_procedure(values...)
,并在其中实现上述逻辑。(假设您可以在应用程序端更改 SQL)。
设置 EVENT 的另一个(但更丑陋)解决方案,它会定期修复您的记录,其中content=NULL