修复我的多表触发器?

时间:2011-11-17 04:38:35

标签: mysql triggers

这是一系列问题中的第三个问题。现在我有了一个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 ;

1 个答案:

答案 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文档。