MYSQL 5.0 中触发器 不能使用变量吗?
————————
trigger a
after delete
on list
for each row
begin 
set @t=deleted.bname
set @q=deleted.num
set @a=old.book_num
set @a=@q+@a
update book set num=@a where book.name=@t
end
————————
在第一个SET那里报错
,小弟不熟悉MYSQL 
求各位大侠帮忙解决这个问题?

解决方案 »

  1.   

    不要使用SESSION级变量,使用你自己定义的变量。MySQL官方文档 http://dev.mysql.com/doc/refman/5.1/zh/index.html
      

  2.   

    trigger a
    after delete
    on list
    for each row
    begin  
    declare t varchar(100);
    declare q int;
    declare a int;set t=deleted.bname
    set q=deleted.num
    set a=old.book_num
    set a=q+a
    update book set num=a where book.name=t
    end
      

  3.   

    create trigger aa
    after delete
    on list
    for each row
    begin   
    declare t varchar(100)
    declare q int
    declare a int
    set t=deleted.bname
    set q=deleted.num
    set a=old.book_num
    set a=q+a
    update book set num=a where book.name=t
    end
    这样改正仍报错
    是不是与MYSQL的版本有关?我的是5.0,另外我还用了NAVICAT作为可视化操作的工具
    另外创建触发器是不是在创建查询里进行?
      

  4.   

    you hava an error in sql syntax;check the maunal that corresponds to you mysql version for the right syntax to use near's declare t varchar(100)
    declare q int
    declare a int
    set t=deleted.bname
    set q=deleted.num at line 6
    ______________create trigger aa            1
    after delete                 2
    on list                      3
    for each row                 4
    begin                        5
    declare t varchar(100)       6
    declare q int                7 
    declare a int                8
    set t=deleted.bname           9
    set q=deleted.num              10
    set a=old.book_num            11
    set a=q+a                     12
    update book set num=a where book.name=t 13
    end                              14
      

  5.   


    建议你能否直接到MYSQL命令工具中执行,这样可以看得清楚一些。另外,你的每一行后面怎么没有; 分号。create trigger aa
    after delete
    on list
    for each row
    begin  
    declare t varchar(100) ;建议你可以先参考一下手册中的例子。这样可以了解一下基本的语法,
    MySQL官方文档 http://dev.mysql.com/doc/refman/5.1/zh/index.html
      

  6.   

    create trigger aa 1
    after delete ;2
    on list ;
    for each row; 4
    begin; 5
    declare t varchar(100) ;6
    declare q int ;7  
    declare a int ;8
    set t=deleted.bname; 9
    set q=deleted.num ;10
    set a=old.book_num; 11
    set a=q+a; 12
    update book set num=a where book.name=t; 13
    end; 14这样写 仍报错啊
      

  7.   

    declare t varchar(100) ;
    declare q int ;   
    declare a int ;
    这三行有错误
      

  8.   


    mysql> create trigger aa
        -> after delete
        -> on list
        -> for each row
        -> begin
        -> declare t varchar(100)
        -> declare q int
        -> declare a int
        -> set t=deleted.bname
        -> set q=deleted.num
        -> set a=old.book_num
        -> set a=q+a
        -> update book set num=a where book.name=t
        -> end;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
    corresponds to your MySQL server version for the right syntax to use near 'decla
    re q int
    declare a int
    set t=deleted.bname
    set q=deleted.num
    set a=old.book' at line 7
    mysql>
      

  9.   

    就是声明变量那有错
    和MS-SERVER的不一样
      

  10.   

    首先,大家别误导LZ!!!LZ的思想是对的,SESSION变量也能用到TRIGGER中去, 只是LZ的临时行集写错了:MySQL 中对于DELETE只有一种行级,那就是OLD。 所以LZ把 自己TRIGGER中的deleted 替换为old就OK了。
      

  11.   

    create trigger d
    after delete 
    on list 
    for each row 
    begin 
    declare t varchar //这里是不是要写长度?  
    declare q int //此行报错
    declare a int 
    set t=old.bname 
    set q=old.num 
    set a=select num from book where name=t
    set a=q+a 
    update book set num=a where book.name=t 
    end ;
    继续求教!
      

  12.   


    例子过于简单
    和我在百度里找的差不多例如其中的NEW行级是代表什么,它就说得很含糊
      

  13.   

    触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。在某些触发程序的用法中,可用于检查插入到表中的值,或对更新涉及的值进行计算。
    触发程序与表相关,当对表执行INSERT、DELETE或UPDATE语句时,将激活触发程序。可以将触发程序设置为在执行语句之前或之后激活。例如,可以在从表中删除每一行之前,或在更新了每一行后激活触发程序。
    要想创建触发程序或舍弃触发程序,可使用CREATE TRIGGER或DROP TRIGGER语句。关于这些语句的语法,请参见21.1节,“CREATE TRIGGER语法”和21.2节,“DROP TRIGGER语法”。
    下面给出了1个简单的示例,在该示例中,针对INSERT语句,将触发程序和表关联了起来。其作用相当于累加器,能够将插入表中某一列的值加起来。
    在下面的语句中,创建了1个表,并为表创建了1个触发程序:
    mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
    mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account    -> FOR EACH ROW SET @sum = @sum + NEW.amount;
    CREATE TRIGGER语句创建了与账户表相关的、名为ins_sum的触发程序。它还包括一些子句,这些子句指定了触发程序激活时间、触发程序事件、以及激活触发程序时作些什么:
    ·         关键字BEFORE指明了触发程序的动作时间。在本例中,应在将每一行插入表之前激活触发程序。这类允许的其他关键字是AFTER。
    ·         关键字INSERT指明了激活触发程序的事件。在本例中,INSERT语句将导致触发程序的激活。你也可以为DELETE和UPDATE语句创建触发程序。
    ·         跟在FOR EACH ROW后面的语句定义了每次激活触发程序时将执行的程序,对于受触发语句影响的每一行执行一次。在本例中,触发的语句是简单的SET语句,负责将插入amount列的值加起来。该语句将列引用为NEW.amount,意思是“将要插入到新行的amount列的值”。
    要想使用触发程序,将累加器变量设置为0,执行INSERT语句,然后查看变量的值:
    mysql> SET @sum = 0;
    mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
    mysql> SELECT @sum AS 'Total amount inserted';
    +-----------------------+| Total amount inserted |+-----------------------+| 1852.48               |+-----------------------+在本例中,执行了INSERT语句后,@sum的值是14.98 + 1937.50 – 100,或1852.48。
    要想销毁触发程序,可使用DROP TRIGGER语句。如果触发程序不在默认的方案中,必须指定方案名称:
    mysql> DROP TRIGGER test.ins_sum;触发程序名称存在于方案的名称空间内,这意味着,在1个方案中,所有的触发程序必须具有唯一的名称。位于不同方案中的触发程序可以具有相同的名称。
    在1个方案中,所有的触发程序名称必须是唯一的,除了该要求外,对于能够创建的触发程序的类型还存在其他限制。尤其是,对于具有相同触发时间和触发事件的表,不能有2个触发程序。例如,不能为某一表定义2个BEFORE INSERT触发程序或2个AFTER UPDATE触发程序。这几乎不是有意义的限制,这是因为,通过在FOR EACH ROW之后使用BEGIN ... END复合语句结构,能够定义执行多条语句的触发程序。请参见本节后面给出的示例。
    此外,激活触发程序时,对触发程序执行的语句也存在一些限制:
    ·         触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL(允许存储程序通过参数将数据返回触发程序)。
    ·         触发程序不能使用以显式或隐式方式开始或结束事务的语句,如START TRANSACTION、COMMIT或ROLLBACK。
    使用OLD和NEW关键字,能够访问受触发程序影响的行中的列(OLD和NEW不区分大小写)。在INSERT触发程序中,仅能使用NEW.col_name,没有旧行。在DELETE触发程序中,仅能使用OLD.col_name,没有新行。在UPDATE触发程序中,可以使用OLD.col_name来引用更新前的某一行的列,也能使用NEW.col_name来引用更新后的行中的列。
    用OLD命名的列是只读的。你可以引用它,但不能更改它。对于用NEW命名的列,如果具有SELECT权限,可引用它。在BEFORE触发程序中,如果你具有UPDATE权限,可使用“SET NEW.col_name = value”更改它的值。这意味着,你可以使用触发程序来更改将要插入到新行中的值,或用于更新行的值。
    在BEFORE触发程序中,AUTO_INCREMENT列的NEW值为0,不是实际插入新记录时将自动生成的序列号。
    OLD和NEW是对触发程序的MySQL扩展。
    通过使用BEGIN ... END结构,能够定义执行多条语句的触发程序。在BEGIN块中,还能使用存储子程序中允许的其他语法,如条件和循环等。但是,正如存储子程序那样,定义执行多条语句的触发程序时,如果使用mysql程序来输入触发程序,需要重新定义语句分隔符,以便能够在触发程序定义中使用字符“;”。在下面的示例中,演示了这些要点。在该示例中,定义了1个UPDATE触发程序,用于检查更新每一行时将使用的新值,并更改值,使之位于0~100的范围内。它必须是BEFORE触发程序,这是因为,需要在将值用于更新行之前对其进行检查:
    mysql> delimiter //mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account    -> FOR EACH ROW    -> BEGIN    ->     IF NEW.amount < 0 THEN    ->         SET NEW.amount = 0;    ->     ELSEIF NEW.amount > 100 THEN    ->         SET NEW.amount = 100;    ->     END IF;    -> END;//mysql> delimiter ;较为简单的方法是,单独定义存储程序,然后使用简单的CALL语句从触发程序调用存储程序。如果你打算从数个触发程序内部调用相同的子程序,该方法也很有帮助。
    在触发程序的执行过程中,MySQL处理错误的方式如下:
    ·         如果BEFORE触发程序失败,不执行相应行上的操作。
    ·         仅当BEFORE触发程序(如果有的话)和行操作均已成功执行,才执行AFTER触发程序。
    ·         如果在BEFORE或AFTER触发程序的执行过程中出现错误,将导致调用触发程序的整个语句的失败。
    ·         
      

  14.   

    首先,看到下面例子中的分号了吗? 你的分号在哪儿? 这个是已经提醒过你一次的了。mysql> delimiter //
    mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account    
    -> FOR EACH ROW    
    -> BEGIN    
    ->     IF NEW.amount < 0 THEN    
    ->         SET NEW.amount = 0;    
    ->     ELSEIF NEW.amount > 100 THEN    
    ->         SET NEW.amount = 100;    
    ->     END IF;    
    -> END;//
    mysql> delimiter 
      

  15.   

    create trigger d
    after delete  
    on list  
    for each row  
    begin  
    declare t varchar(255) ;   
    declare q int ;
    declare a int  ;
    set t=old.bname;  
    set q=old.num  ;
    set a=select num from book where name=t;
    set a=q+a  ;
    update book set num=a where book.name=t  ;
    end ;
    在定义变量那几行还是报错
      

  16.   

    create trigger d
    after delete  
    on list  
    for each row  
    begin  
    declare t varchar(255);    
    declare q int ;
    declare a int  ;
    set t=old.bname;  
    set q=old.num  ;
    set a=select num from book where book.name=t;//报错
    set a=q+a  ;
    update book set num=a where book.name=t  ;//报错
    end ;
      

  17.   


    create trigger d
    after delete   
    on list   
    for each row   
    begin   
    declare t varchar(255);   
    declare q int ;
    declare a int ;
    set t=old.bname;   
    set q=old.num ;
    set a=(select num from book where book.name=t);//报错
    set a=q+a ;
    update book set num=a where book.name=t ;//报错
    end ;
      

  18.   

    set a=(select num from book where book.name=t);