存储过程与触发器:
Mysql有关存储过程与触发器详解:
定义:存储过程主要将业务逻辑在数据库层加以实现,使得web应该用层的压力变小。
缺点:是每一个数据库厂商对存储过程的语法规范不同导致很难移植该业务逻辑。
案例:对于一些比较敏感的领域如金融领域开发者在处理业务逻辑的时候不能使用javabean
在这里为了安全期间,必须使用存储过程进行封装业务逻辑,因为存储过程可以加密。
创建存储过程:
?
准备工作:
在创建存储过程前,必须修改MySQL的默认的结束符号。
delimiter //
语法:
create procudure 存储过程名(参数列表)
begin
SQL语句;
end //
例子1:
mysql> create database db2; --->创建数据库
Query OK, 1 row affected (0.00 sec)
mysql> create table user( --->创建表
-> id int primary key,
-> name varchar(10));
Query OK, 0 rows affected (0.17 sec)
mysql> insert into user values(1,'zhangsan'); ---->添加数据
Query OK, 1 row affected (0.08 sec)
mysql> insert into user values(2,'lisi');
Query OK, 1 row affected (0.08 sec)
mysql> delimiter // --->创建存储过程(修改结束符为//)
mysql> create procedure pro1()
-> begin
-> select count(*) as allusers from user;
-> end//
Query OK, 0 rows affected (0.12 sec)
mysql> call pro1()// ---->调用存储过程
+----------+
| allusers |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
带参数的存储过程:
在存储过程中有时候需要指定形参,在MySQL中参数不仅有数据类型、变量名还有作用类型。
作用类型:IN OUT INOUT
创建带参的存储(in):
mysql> create procedure pro2(in name varchar(10)) 定义一个输入型参数
-> begin
-> select name;
-> set name='lucy';
-> select name;
-> end//
mysql> set @name='jack';// --->定义用户变量
查询用户变量
mysql> select @name;// ------>查询用户变量
+-------+
| @name |
+-------+
| jack |
+-------+
1 row in set (0.03 sec)
mysql> call pro3(@name);// ---->调用存储过程传递用户变量
+------+
| name |
+------+
| jack |
+------+
1 row in set (0.04 sec)
+------+
| name |
+------+
| lucy |
+------+
1 row in set (0.05 sec)
Query OK, 0 rows affected (0.05 sec)
OUT参数:
mysql> create procedure pro4(out name varchar(10))
-> begin
-> select name;
-> set name='lucy';
-> select name;
-> end//
Query OK, 0 rows affected (0.00 sec)
mysql> set @myname='rose';//
Query OK, 0 rows affected (0.00 sec)
mysql> call pro4(@myname);//
+------+
| name |
+------+
| NULL | ---->因为该参数的返回值的作用类型,只保存业务逻辑的数据,所以为空。
+------+
1 row in set (0.00 sec)
+------+
| name |
+------+
| lucy |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
InOut参数:
mysql> create procedure pro5(inout name varchar(10
-> begin
-> select name;
-> set name='lisi';
-> select name;
-> end//
Query OK, 0 rows affected (0.01 sec)
mysql> set @myname='wangwu';//
Query OK, 0 rows affected (0.00 sec)
mysql> call pro5(@myname);//
+--------+
| name |
+--------+
| wangwu |
+--------+
1 row in set (0.00 sec)
+------+
| name |
+------+
| lisi |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
局部变量的定义:
declare 变量名 数据类型 指定默认值;
举例:
declare l_int int unsigned default 100;
案例:计算1~n的累加和?
分析:该实例中必须要定义一个变量来保存计算的结果?需要学习如何在存储过程体中定义局部变量?
mysql> create procedure getsum(in num int)
-> begin
-> declare sum int default 0;
-> declare i int default 0;
-> while i<=num do
-> set sum=sum+i;
-> set i=i+1;
-> end while;
-> select sum;
-> end//
自己练习:定义一个用户变量来接收计算的结果数据?
创建存储过程:
create procedure getout(out outdate int)
begin
declare i int default 0;
declare sum int default 0;
while i <= 10 do
set sum = sum + i;
set i = i + 1;
end while;
set outdate = sum;
end//
定义变量用于接收结果:
set @sum=0//
调用存储过程:
call getout(@sum)//
查询返回结果:
select @sum//
在存储过程中使用IF ELSE 语句
语法:
IF 条件 THEN
语句
ELSE
语句
END IF;
注意:条件语句中没有双等号的
举例:
CREATE PROCEDURE p12 (IN parameter1 INT)
BEGIN
DECLARE variable1 INT;
SET variable1 = parameter1 + 1;
IF variable1 = 0 THEN
INSERT INTO t VALUES (17);
END IF;
IF parameter1 = 0 THEN
UPDATE t SET s1 = s1 + 1;
ELSE
UPDATE t SET s1 = s1 + 2;
END IF;
END; //
CASE指令
举例:
CREATE PROCEDURE p13 (IN parameter1 INT)
BEGIN
DECLARE variable1 INT;
SET variable1 = parameter1 + 1;
CASE variable1
WHEN 0 THEN INSERT INTO t VALUES (17);
WHEN 1 THEN INSERT INTO t VALUES (18);
ELSE INSERT INTO t VALUES (19);
END CASE;
END; //
Loops 循环语句
LOOP循环是靠标记和LEAVE语句结束的!
举例:
CREATE PROCEDURE p16 ()
BEGIN
DECLARE v INT;
SET v = 0;
loop_label: LOOP --->作一个标志
INSERT INTO t VALUES (v);
SET v = v + 1;
IF v >= 5 THEN
LEAVE loop_label; ----> 利用标志结束循环
END IF;
END LOOP;
END; //
WHILE循环:
举例:
CREATE PROCEDURE p14 ()
BEGIN
DECLARE v INT;
SET v = 0;
WHILE v < 5 DO
INSERT INTO t VALUES (v);
SET v = v + 1;
END WHILE;
END; //
REPEAT 循环:
与 do-while相同,他用until结束
举例:
CREATE PROCEDURE p15 ()
BEGIN
DECLARE v INT;
SET v = 0;
REPEAT
INSERT INTO t VALUES (v);
SET v = v + 1;
UNTIL v >= 5
END REPEAT;
END; //
触发器的语法:
create trigger 触发器名字 指定执行的时间 on 指定在什么表上执行操作
影响的函数 需要执行的任务或业务
举例:
创建数据表,用于表示文章
create table data(
name varchar(20)
);
创建数字表,用于表示文章的字数
create table chars(
count int(10)
);
插入初始化数据
insert into chars (count) values (0);
创建触发器
create trigger tr1 --->指定触发器的名字
after insert --->指定当什么时候触发
on data --->指定当哪个表作操作时触发
for each row --->指定具体的影响程度(每一行变化都触发)
update chars set count=count+char_length(new.name); --->指定触发时,执行的操作
char_length(new.name) --->函数是获取更新的所有字符的长度。
注意:触发器不要单独的调用。主要发生相应的事件MySQL会自动调用。