我希望有一个触发器来执行插入记录的以下操作:
# pseudocode
if new.group_id is null
set new.group_id = new.id
else
# don't touch it
end
更清楚地说:我有一个包含三列的表:id
主键,group_id
int,value
varchar。
当我使用group_id
插入时:
INSERT INTO table(value, group_id) VALUES ('a', 10)
我想:
id | group_id | value
---+----------+------
1 | 10 | a
但是当我省略group_id
时:
INSERT INTO table(value) VALUES ('b')
它应自动设置为此记录的id
:
id | group_id | value
---+----------+------
2 | 2 | b
是否可以使用触发器? (我知道我可以在插入后更新记录,但触发器会更好。)
答案 0 :(得分:27)
即使使用触发器,我也不知道如何在一个声明中做到这一点。
@Lucky建议的触发器解决方案在MySQL中看起来像这样:
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END
但是,有一个问题。在BEFORE INSERT
阶段,尚未生成自动生成的id
值。因此,如果group_id
为空,则默认为NEW.id
,始终为0.
但是如果您在AFTER INSERT
阶段将此触发器更改为触发,那么您可以访问生成的NEW.id
值,则无法修改列值。
MySQL不支持列的DEFAULT
表达式,因此您也不能在表定义中声明此行为。
唯一的解决方案是执行INSERT
,然后立即执行UPDATE
更改group_id
(如果未设置)。
INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();
答案 1 :(得分:1)
我在这里回答,如接受的答案Bill Karwin所述:
在BEFORE INSERT阶段,自动生成的id值尚未出现 生成了。因此,如果group_id为null,则默认为NEW.id 总是0。
我有一个答案 - 对于OP(以及来访的访客),这里有几点: 您无法更新触发器调用位置的表格,因为您将获得错误1442 :
Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
1.更新新行
使用BEFORE INSERT ON
触发器,这样您就可以更新新行的所有字段,可以通过NEW运算符访问,即
set NEW.group_id = NEW.id
2.插入前获取auto_increment值:
SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'
总结一下 - 'd的触发器SQL如下:
DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
IF new.group_id IS NULL
set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() );
set NEW.group_id = @auto_id;
ENF IF;
END;
//
DELIMITER ;
答案 2 :(得分:1)
这对我有用
DELIMITER $$
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$$
DELIMITER ;
答案 3 :(得分:0)
我相信这对你有用
我有两张桌子
test_b: a_id, value
test_c: a_id, value
这是插入测试b的触发器。它检查a_id是否为null,如果是,则插入0
CREATE TRIGGER test_b AFTER INSERT ON test_b
FOR EACH ROW
INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)
答案 4 :(得分:-2)
此触发器应该按照您的要求执行。
CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
IF new.group_id IS NULL
SET new.group_id = new.id
END IF
END;
它是从MYSQL documentation页面中非常相似的示例复制而来的。
答案 5 :(得分:-3)
在这种情况下,触发器似乎有些过分。只需应用默认值。
CREATE TABLE `test` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`value` varchar(100) NOT NULL,
`group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)