错误1:declare位置错误
declare定义局部变量,只能用于begin和end之间(目前似乎是这样的),而且是必须在begin后面直接跟着,即写在最开始。
举例:
create procedure fmpass(in user_name varchar(20), in passw varchar(20),
in newpass varchar(20), in actions int, out resu boolean)
begin
declare done boolean default false;
declare a,b varchar(20);
declare cur1 cursor for select userss,passwordss from acount;
declare continue handler for not found set done = true, resu = false;
set resu = false;
……
end
这样写是对的。我当时犯的错误就是begin下面先写set resu = false,这样会报错。
错误2:写完if没有end if
SQL语言不是按缩进对齐的,也没有大括号来表示作用域(一般情况下),所以写完if后一定要加上end if。否则会导致莫名其妙的错误。
错误3:调用存储过程时OUT类型对应传入的不是用户变量
当存储过程有OUT类型的返回值时,调用此存储过程时,对应返回值的位置上要传入用户变量。所谓用户变量,就是在变量名前加个@。
举例
call fmpass('ca','frws3','22333',1,@result1);
select @result1;
这样是正确的,这里可以在最前面加上set @result1 = ...用于初始化,也可以不加,MySQL会在检测到没有此用户变量后自动创建。
注意1:如果想使用now()函数来获取当前时间,对应类型必须是timestamp
正确代码举例如下(注释的是错误代码):
alter table record modify column borrow timestamp default NOW();
#alter table record modify column borrow date default NOW();
注意2:触发器中的new与old使用和修改数据
在触发器中是不允许修改当前表的非当前操作数据的,防止自身无限次触发(可以修改非当前触发器所在表或者修改要插入的数据)。要想对当前操作行的数据修改,就要用new或者old。插入和修改用new,删除用old。具体来说,new和old就相当于当前操作的一行。
例如:
create trigger ooo before insert on record
for each row
begin
set new.DDL = date_add(new.borrow, interval 30 day);
end;
这就是修改当前插入的数据,或者修改其他表的数据,如:
create trigger triDEL after delete on sells
for each row
begin
declare priceall int default 0;
...
else
update customer set level = 'normal' where cid = old.cid;
end if;
end;
可以看到这里是在sells表删除数据后触发,使用的是old。
注意3:一个触发器只能对一个表的一种操作触发
以下写法是不允许的
create trigger t1 before insert on Male or before insert on Female
for each row
begin
...
end;
不能在Male插入前或者Female插入前触发,只能选一种情况。也就是要分开写两种情况的触发器。
注意4:词的顺序
不能想写哪个就写哪个,SQL语句一般都是有固定的现后顺序的。
#select numbers from books into curnum where ISBN = in_ISBN;
select numbers into curnum from books where ISBN = in_ISBN;
上述注释的代码就是错误的,没注释的代码是正确的。