我试图创建触发器,它可以使用表user_info的u_count值更新表user_details的列user_count的值。
CREATE TRIGGER `test`
AFTER INSERT ON `user_details` FOR EACH ROW
BEGIN
DECLARE default_user_count int(11);
SELECT u_count INTO @default_user_count FROM
user_info WHERE user_info.id= user_details.id_c;
IF user_details.user_count= 0
THEN UPDATE user_details SET
user_count = default_user_count
WHERE user_details.id_c = user_info.id;
END IF;
END
触发器保存成功,但是当我试图在两个表中插入值时,它阻止将记录插入user_details表示没有在该表中插入行,如果我们删除触发器然后它的工作。
任何人都可以让我知道这个触发器的错误吗?
谢谢, 微米。
答案 0 :(得分:1)
它并不是很清楚你想要完成什么,但它似乎就像我们在下面所做的那样。
触发器中存在许多错误和含糊之处。
对变量的混淆 - DECLARE default_user_count INT(11);
不声明用户定义的变量@default_user_count
。它声明了程序变量default_user_count
。 @
前缀引用完全不同的变量范围和命名空间。
SELECT
和UPDATE
通常没有意义(SELECT
)或完全无效(UPDATE
)
在触发器中,您正在操作FOR EACH ROW
- 也就是说,对于调用触发器的语句中包含的每一行。在INSERT
触发器内,该行的NEW
值位于通过别名NEW
可访问的伪表/伪行中。对于UPDATE
触发器,有NEW
和OLD
行值,对于DELETE
触发器,只有OLD
。
AFTER INSERT
似乎没有意义。我认为您正在寻找BEFORE INSERT
- 也就是说,在处理INSERT INTO ...
查询时,在之前,新插入的行实际上会写入表中,修改它的价值相应。生成的行包含原始值,除非触发器已修改它们。
SELECT ... INTO
变量是一种习惯,你不应该养成习惯,因为it can bite you in a way a scalar subquery can't,通过让变量意外地保持不变而不是将其设置为NULL
。被期望。在这种情况下,它没有任何区别,但它仍然是值得一提的谨慎......在这种情况下,我完全消除了这个中间变量,所以子查询是唯一的选择。
如果您尝试使用在另一个表中找到的值在此表中设置值,则您需要做的只是SET NEW.column_name
等于您要在行中使用的值,而不是在行中提供的值。插入声明。
CREATE TRIGGER `test`
BEFORE INSERT ON `user_details` FOR EACH ROW
BEGIN
IF NEW.user_count = 0 /* maybe also >> */ OR NEW.user_count IS NULL /* << this */ THEN
SET NEW.user_count = (SELECT ui.u_count
FROM user_info ui
WHERE ui.id = NEW.id_c);
END IF;
END
同样,根据原始问题的内容,目前还不清楚这两个表是如何连接的,但这似乎是你要完成的事情。