这是一系列问题中的第三个问题。现在我有了一个MySQL触发器,它将一个表中的一行更新为一个单独表中一行的新值。
以下是一些视觉效果:
CREATE TABLE As (
id
a
) ENGINE MyISAM
CREATE TABLE Bs (
id
b
) ENGINE MyISAM
CREATE TABLE AbyB (
id
aid
bid
)
ROWS
| A | B | AbyB |
id| 1 | 2 | 0 |
a | i | x | x |
b | x | i | x | --> | x | 0 | x |
aid | x | x | 1 |
bid | x | x | 2 |
INSERT INTO table1 VALUES(1);
DELIMITER $$
CREATE TRIGGER dualupdate() BEFORE INSERT INTO Bs.b
BEGIN
SET @a = 'SELECT NEW.b'; #I don't know if I should use NEW, actually.
SET @b = 'SELECT NEW.id';
SET @x = 'SELECT aid FROM AbyB WHERE bid = @b';
UPDATE As
SET a = @a #SET is used to set variables, right? So, am I using it wrong?
WHERE id = @x;
END$$
DELIMITER ;
答案 0 :(得分:1)
你犯了一些错误,下面是正确的代码:
DELIMITER $$
CREATE TRIGGER ai_Bs_each AFTER INSERT ON Bs FOR EACH ROW
BEGIN
UPDATE `As`
SET a = New.b
WHERE id IN (SELECT aid FROM AbyB WHERE bid = NEW.id);
END$$
DELIMITER ;
以下是您所犯错误的简要说明:
CREATE TRIGGER dualupdate() BEFORE INSERT INTO Bs.b
//This is incorrect syntax.
//This should really be an AFTER INSERT trigger. If the insert fails `As` will
//be incorrectly updated. Not unless you want to prevent the insert if the
//update does not succeed.
BEGIN
SET @a = 'SELECT NEW.b'; #I don't know if I should use NEW, actually.
//You're filling @a with a string containing the words `select` and `new`.
//SET @a = NEW.b; will work better.
SET @b = 'SELECT NEW.id';
SET @x = 'SELECT aid FROM AbyB WHERE bid = @b';
//This is a fundamental error, you can only ever put 1 result in a variable,
//not a resultset.
//If you want to use multiple values, put the select inside the update statement.
//See my updated code.
UPDATE As
SET a = @a #SET is used to set variables, right? So, am I using it wrong?
WHERE id = @x;
//This statement is (almost) correct, However `as` is a reserved word and needs
//to be escaped in backticks `
END$$
这里不需要变量。您可以直接使用NEW.?
另请注意,MySQL不支持每个语句的触发器,仅支持每行。但是,将来这可能会发生变化,因此您必须包含for each row
。
请参阅:http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
并且:http://dev.mysql.com/doc/refman/5.0/en/update.html
MySQL文档非常好,只是google mysql statement_to_find
,第一个或第二个结果应该指向MySQL文档。