2011-11-16 45 views
0

有人告诉我,我需要在我的触发器中使用分隔符。我正在查看MySQL手册页,并在示例中找到它;但是,它不在通用文档中。MySQL:如何在触发器中使用分隔符?

这里我想纠正代码:

CREATE TRIGGER adult BEFORE INSERT OR UPDATE ON table5.column5 
FOR EACH ROW BEGIN 
    UPDATE table1 SET column5 = table5.column5 WHERE table5id = table1xtable5.table5id WHERE table1xtable5.table1id = OLD.table1.id$ 
END$ 

老实说,我不知道如何做到这一点,并在http://dev.mysql.com/doc/refman/5.5/en/create-trigger.html文件似乎是一个可怕的不足参考。例如,在阅读“old”和“new”时,它会引用“subject table” - 与触发器关联的表格。有两个表与这个触发器相关联,我实际上试图将更多的表与这个触发器联系起来....当查看示例代码时,影响表4的UPDATE行仅使用表4中的列(他们'重新添加1的值)。此外,他们正在使用WHERE ~ a3 = NEW.a1。我不认为这个ID的工作就是这样。不应该有跨表格工作的通用标识。在示例中,它们应该一定要使用相互依赖关系表,以便适用。

我实际上在今天早些时候问过一个类似的问题,关于这么做的好方法是什么,但现在我想知道,简单地说,如果有一种方法。谢谢阅读。 :)

这里是更新另一个表的触发器的例子,但它似乎没有使用分隔符:

CREATE TRIGGER mytrigger BEFORE INSERT ON odp 
FOR EACH ROW 
    UPDATE total_points SET points = points + NEW.points; 

什么都不用在这个例子说明的是如何odptotal_points重叠。我们如何确定total_points表的points行是正确的points行? MySQL中更新哪个表的points表中的哪一行? x //

因此,不应该有某种方法来指定要更新哪个total_points.points行BEFORE INSERT ON odp

+0

这是$$代替; – matino

回答

4

第1部分

定界符用于相同的存储过程/功能,触发或事件源对象。所有这些对象在BEGIN ... END子句中都可能有一个正文代码。

MySQL脚本中的所有语句都应以分隔符结束,默认值为';'。但是如果源对象具有一些语句e,g,则该怎么办:

INSERT INTO table1 VALUES(1); 

CREATE PROCEDURE procedure1() 
BEGIN 
    SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 
    PREPARE stmt2 FROM @s; 
    SET @a = 6; 
    SET @b = 8; 
    EXECUTE stmt2 USING @a, @b; 
END; 

INSERT INTO table1 VALUES(2); 

有多少个状态? 3或8?答案是三,因为脚本有两个INSERT和一个CREATE PROCEDURE语句。正如你看到的,CREATE PROCEDURE也有一些内部的陈述。我们应该对MySQL客户端说,所有这些语句(在BEGIN ... END内) - 都是ONE语句的一部分;我们可以用分隔符的帮助下做到这一点:

INSERT INTO table1 VALUES(1); 

DELIMITER $$ 

CREATE PROCEDURE procedure1() 
BEGIN 
    SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 
    PREPARE stmt2 FROM @s; 
    SET @a = 6; 
    SET @b = 8; 
    EXECUTE stmt2 USING @a, @b; 
END$$ 

DELIMITER ; 

INSERT INTO table1 VALUES(2); 

注意,当你触发已经没有BEGIN ... END子句,分隔符可以省略。


第2部分

无定界符的语句将被解析为 -

CREATE PROCEDURE procedure1() 
BEGIN 
    SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 

代替 -

CREATE PROCEDURE procedure1() 
BEGIN 
    SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 
    PREPARE stmt2 FROM @s; 
    SET @a = 6; 
    SET @b = 8; 
    EXECUTE stmt2 USING @a, @b; 
END 
+1

如果你有“开始”和“结束”,它为什么重要?看起来会使分隔符不必要 –

+1

@ Wolfpack'08因为你可以嵌套开始块。 MySQL不会跟踪开始 - 结束嵌套数。 – Johan

+0

分隔符帮助客户理解语句的起始位置和结束位置。我已经添加了示例。 – Devart

0

运行:

delimiter $$ 

运行CREATE

+0

你能告诉我为什么这很重要吗? –

+0

(您似乎已更改了代码)您的创建中有分号。你需要告诉MySQL这些分号不会结束语句。 – smp7d

0

更新查询之前你触发内运行是像任何其他更新查询,但它的触发内运行。现在您正在更新所有记录并递增点字段。如果您只想将其限制为与导致触发器触发的任何相关的特定记录,则必须将其添加到UPDATE查询的WHERE子句中。

MySQL已经知道你的意图与UPDATE查询是什么,就像它不知道你在做正常的插入/更新/删除时的真正含义 - 这取决于你指定了必须完成的工作。因为你正在创造一些全新的东西(除非它是一个插入...在重复键更新的情况下)。在INSERT触发器的情况下,通常不会有“旧”记录来引用。