题
我想要有一个触发执行下列操作插入记录:
# 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
它是可能带有触发?(我知道我可以更新的记录之后插入的,但具有触发,将会更好。)
解决方案
我不知道的任何方式做到这一声明中,甚至采用一种触发。
触发解决方案,@幸运的建议将会看起来像这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();
其他提示
我在这里回答,正如接受的答案 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 ;
这对我有用
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 ;
我相信这对你有用
我有两张桌子
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)
此触发器应该按照您的要求执行。
CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
IF new.group_id IS NULL
SET new.group_id = new.id
END IF
END;
它是从 MYSQL文档中的一个非常相似的示例中复制而来的页面。
在这种情况下,触发器似乎有些过分。只需应用默认值。
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'
)