我试图创建以下触发器,但我有一个错误。我可以在触发器中使用update或case-when吗?请帮我解决这个问题。
代码说明:我想在插入或更新后更新现有行。如果我没有向“fusdate1”或“fusdate2”添加任何内容,请不要更改“fusdate1”或“fusdate2”
将fusdate更新为新的fusdate,如果我将数据更新或插入到fusdate,则更新插入的fusdate
代码:
delimiter //
create trigger SafetyCertificationTRG
after insert on SafetyCertification
for each row
begin
case when (FUSDate1='' or FUZDate1 is NULL) then (FUZDate1=OLD.FUSDate1) else (update SafetyCertification set FUZDate1=NEW.FUSDate1) end;
case when (FUSDate2='' or FUZDate2 is NULL) then (FUZDate2=NEW.FUSDate2) else (update SafetyCertification set FUZDate2=NEW.FUSDate2) end;
end //
delimiter ;
编辑:我将在这里添加一些信息,使问题更清楚。
我有一列作为fus,它只能获取这3个值:('fus1'、'fus2'和'fus3')我还有3列:fusdate1、fusdate2、fusdate3。
我想根据用户选择的fus将当前日期保存到fusdate1、fusdate2或fusdate3(他们在同一张table上)
我使用了提供的答案,并更改为这个,但我不能做上述。
代码:此代码仅适用于fus1和fusdate1
delimiter //
CREATE TRIGGER SafetyCertification_bu
BEFORE UPDATE ON SafetyCertification
FOR EACH ROW
BEGIN
-- detect a change made to a value in col
IF OLD.FUS <=> NEW.FUS THEN
-- value of col is not changed, so do nothing
DO 0;
ELSE
-- we detected a new value was assigned to col
IF OLD.FUS ='%FUS1%' THEN
-- we can override the new value, keep it the same
SET NEW.FUSDate1 = CURDATE();
END IF;
END IF;
END //
delimiter ;
另一个代码,我希望做我的工作,但仍然有问题,不更新像上面的代码:
delimiter //
CREATE TRIGGER SafetyCertification_bu
BEFORE INSERT ON SafetyCertification
FOR EACH ROW
BEGIN
IF NEW.FUS='%FUS1%' THEN
SET new.FUSDate1=MD5(CURDATE());
END IF;
END //
delimiter ;
更新3:
在更新或插入任何数据时,answer中提供的第三个代码不会向fusdate1、2和3添加任何内容。
代码
DELIMITER $$
CREATE TRIGGER SafetyCertification_bu
BEFORE UPDATE ON SafetyCertification
FOR EACH ROW
BEGIN
-- set one of the `fusdateN` columns to current date
-- which column to set depends on the value assigned to `fus`
IF NEW.fus = 'FUS1' THEN
SET NEW.fusdate1 = DATE(NOW());
ELSEIF NEW.fus = 'FUS2' THEN
SET NEW.fusdate2 = DATE(NOW());
ELSEIF NEW.fus = 'FUS3' THEN
SET NEW.fusdate3 = DATE(NOW());
END IF;
END$$
DELIMITER ;
2条答案
按热度按时间py49o6xq1#
几个注意事项:
触发器不能对触发触发器的表发出更新,这是禁止的。
不合格的参考文献(如。
FUSDate1
以及FUZDate1
)无效。那些参考资料不能解决任何问题。引用
OLD.FUSDate1
在插入后触发器的上下文中无效。在更新触发器中OLD.col
更新前列的值。表达式
(FUZDate1=OLD.FUSDate1)
不是赋值,而是将返回0、1或null的比较。如果我们想触发
UPDATE
和一个INSERT
,这将需要两个单独的触发器。如果要修改当前行的内容,可以使用
BEFORE
触发而不是AFTER
.我想在插入或更新后更新现有行。
在插入或更新行之前应用更改要容易得多。我们可以给一列赋值
col
通过引用NEW.col
在学校的作业中BEFORE INSERT
或者BEFORE UPDATE
触发。例如:不要改变方向
FUSDate1
或者FUSDate2
如果我不加任何东西FUSDate1
或者FUSDate2
这看起来很简单。只是别给我分配任务NEW.FUSDate1
或者NEW.FUSDate2
.将fusdate更新为新的fusdate,如果我将数据更新或插入到fusdate,则更新插入的fusdate
建议的触发器示例包含对
FUZDate1
或者FUZDate2
,但规范中没有提到这些列。说明书很混乱。一
UPDATE
语句将为列赋值,而不需要触发器。一INSERT
语句可以为列赋值,同样,也不需要为此设置触发器。规格不清楚。提供示例起始状态(表中的行)和示例insert或update语句,以及执行语句后所需的状态,将大大有助于澄清需求。
演示
BEFORE UPDATE
阻止将新值赋给特定列的触发器:对于这个示例触发器实现的功能,我们不一定需要那么多
IF
条件;这些都是为了演示我们可以执行的一些检查,以及如何引用col
以及分配给col
.后续行动
根据问题中的更新信息,下面是一个
BEFORE UPDATE
符合规范的触发器。这是给
UPDATE
行动。为了得到同样的行为INSERT
语句,则需要重复此触发器定义BEFORE INSERT
代替BEFORE UPDATE
.(我会用这个名字
_bu
对于更新前触发器,以及_bi
用于插入触发器之前。)第二次随访
回答关于使用
CASE WHEN
mysql存储程序上下文中的语句。。。我们可以实现示例触发器(在这个答案的正上方)来替换
IF-THEM
两种形式的CASE
声明。任何一个
-或者-
笔记
这个
CASE
语句在mysql存储程序中可用;在存储程序之外,它不是有效的sql语句。另外,我们不应该将这个case语句与case表达式混淆。case表达式在sql语句的上下文中有效,例如
SELECT
或者UPDATE
声明。示范
“我检查了触发器,但不幸的是没有保存任何内容。”
@克里斯蒂亚诺:这里有一个简单的演示
创建表
用演示行填充表
创建触发器
更新将在我们刚刚定义的更新触发器之前执行
显示表格内容
退货:
当一些特定的值被分配给fus时,触发器似乎正在按照规范填充fusdate1、fusdate2和fusdate3列
rmbxnbpk2#
我也遇到了同样的问题,我使用了两个触发器,第一个触发器将数据发送到另一个表,所以现在可以创建另一个触发器将数据发送到第一个表。我认为这是低性能,但这是我达到它的唯一途径。我希望其他人有另一个解决方案。