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
求各位大侠帮忙解决这个问题?
————————
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
求各位大侠帮忙解决这个问题?
解决方案 »
- mySql查询表达式
- mysql多列索引问题
- mysql怎么让varchar类型自动增长
- MYSQL嵌套查询问题
- ★★为什么我连接mysql失败?
- 高分求助:MySql中用什么方法实现触发器功能?
- 关于MYSQL的OLE DB驱动问题
- innodb_flush_log_at_trx_commit & sync_binlog大家在生产环境中都怎么设置啊?
- 在线等。。。mysql文件执行不成功,但文件里面的语句应该没有问题,因为把sql文件中的内容在查询中能够执行,这是咋回事啊
- 使用MySQL可以开发电影视频网站吗?
- phpmyadmin中,提示:链接表的额外特性尚未激活,什么意思呀?
- innodb 表修复问题,select错误ERROR 1033 (HY000):Incorrect information in file: './blog/b
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
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作为可视化操作的工具
另外创建触发器是不是在创建查询里进行?
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
建议你能否直接到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
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这样写 仍报错啊
declare q int ;
declare a int ;
这三行有错误
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>
和MS-SERVER的不一样
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 ;
继续求教!
例子过于简单
和我在百度里找的差不多例如其中的NEW行级是代表什么,它就说得很含糊
触发程序与表相关,当对表执行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触发程序的执行过程中出现错误,将导致调用触发程序的整个语句的失败。
·
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
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 ;
在定义变量那几行还是报错
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 ;
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 ;