MySQL学习笔记九:存储过程,存储函数,触发器

存储过程

1.存储过程由一组特定功能的SQL语句组成,对于大型应用程序优势较大,相对不使用存储过程,具有以下优点:

  a.性能提高,因为存储过程是预编译的,只需编译一次,以后调用就不须再编译

  b.重用性提高,可以“一次编写,随便调用”

  c.安全性提高,可以一定程度上防止SQL注入,还可以使用权限控制

  d.减少网络流量,提高网站访问速度

2.存储过程的建立,使用create procedure语句,语法如下

CREATE
    [DEFINER = { user | CURRENT_USER }]
    PROCEDURE sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

CREATE
    [DEFINER = { user | CURRENT_USER }]
    FUNCTION sp_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...] routine_body

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

func_parameter:
    param_name type

type:
    Any valid MySQL data type

示例:

use test;
delimiter $$  //改变语句分隔符
create procedure test(in a varchar(10),out b int)  //in 输入参数 out 输出 inout 输入输出
begin

select concat(‘hello ‘,a);
select count(1) into b from tb_6;

end$$

delimiter ;
call test(‘world‘,@c);  //使用call调用存储过程
select @c;

参数为INOUT示例

delimiter $$

create procedure test(inout b int)
begin

select b;
set b=10;
select b;
select count(1) into b from tb_5;

end$$

delimiter ;
set @b = 100;
call test(@b);
select @b;

--------------------------结果-----------------------
mysql> call test(@b);
+------+
| b    |
+------+
|   20 |
+------+
1 row in set (0.00 sec)

+------+
| b    |
+------+
|   10 |
+------+
1 row in set (0.01 sec)

Query OK, 1 row affected (0.04 sec)

mysql> select @b;
+--------+
| @b     |
+--------+
| 120832 |
+--------+
1 row in set (0.00 sec)

变量的定义,赋值,以及用户变量示例

delimiter $$

create procedure test()
begin

declare i int default 1;  --变量的定义
select i;
set i = 100;  --变量的赋值
select i;

end$$

delimiter ;
//结果
mysql> call test();
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

+------+
| i    |
+------+
|  100 |
+------+
1 row in set (0.01 sec)

mysql> set @t=‘hehe‘;  --用户变量
Query OK, 0 rows affected (0.00 sec)

mysql> select @t;
+------+
| @t   |
+------+
| hehe |
+------+
1 row in set (0.00 sec)

3.存储过程的更改,删除

ALTER PROCEDURE proc_name [characteristic ...]

drop procedure proc_name

4.查看存储过程的信息

mysql> select name from mysql.proc where db=‘test‘;
+----------+
| name     |
+----------+
| add_user |
| partPage |
| test     |
+----------+
3 rows in set (0.00 sec)

--或者使用show create procedure proc_name

5.存储过程的控制结构

if-then-else-end if语句

delimiter $$
create procedure proc(in i int,out res varchar(30))
begin

declare j int;
set j = 20;
if i<j then
set res = ‘i is smaller than j‘;
else
set res = ‘i is bigger than j‘;
end if;

end
--结果
mysql> call proc(30,@ret);
Query OK, 0 rows affected (0.00 sec)

mysql> select @ret;
+--------------------+
| @ret               |
+--------------------+
| i is bigger than j |
+--------------------+
1 row in set (0.00 sec)

case-when-then-end case语句

delimiter $$
create procedure proc(in i int,out res varchar(30))
begin
case i
when 1 then
set res=‘星期一‘;
when 1 then
set res=‘星期二‘;
when 1 then
set res=‘星期三‘;
when 1 then
set res=‘星期四‘;
when 1 then
set res=‘星期五‘;
when 1 then
set res=‘星期六‘;
when 1 then
set res=‘星期日‘;
end case;
end$$
--结果
mysql> call proc(1,@ret);
Query OK, 0 rows affected (0.03 sec)

mysql> select @ret;
+--------+
| @ret   |
+--------+
| 星期一 |
+--------+
1 row in set (0.03 sec)

循环while-do-end while语句

DELIMITER $$

CREATE  PROCEDURE `add_user`()
begin
declare i int default 1;
while i<=50 do

insert into users(userName,email,passwd,registion_date) values(concat(‘zhumuxian‘,i),concat(‘zhumuxian‘,i,‘@163.com‘),sha1(‘1234567‘),now());
set i=i+1;

end while;

end

示例,分页存储过程

CREATE  PROCEDURE `partPage`(in perPageNum int ,in currentPage int)
begin

declare perNum int default 10;
declare curPage int default 1;
declare start0 int ;

set perNum=perPageNum;
set curPage=currentPage;

set start0=(curPage-1)*perNum;
select user_id,userName,email,registion_date from users limit start0,perNum;

end

存储函数与存储过程在语法上有点类似,不同点:

  存储函数需要返回一个类型,且函数体中必须要有一个有效的return语句。

  它们调用的方式不同,过程使用call调用,函数使用select调用。

  函数只能返回一个结果值,而过程可以返回一个或多个结果集,等等。

存储函数的创建,语法如下

CREATE
[DEFINER = { user | CURRENT_USER }]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body

创建示例

delimiter $$
create function getDate()
returns varchar(255)
begin
declare str varchar(255) default ‘0000-00-00 00:00:00‘;
set str = date_format(now(),‘%Y年%m月%d日 %H时%i分%S秒‘);
return str;
end $$
delimiter ;

--结果
mysql> select getDate();
+-----------------------------+
| getDate()                   |
+-----------------------------+
| 2015年04月16日 15时16分46秒 |
+-----------------------------+
1 row in set (0.08 sec)

如在创建函数时碰到ERROR 1418 (HY000)错误,可以设置log_bin_trust_function_creators=TRUE即可。

mysql> show variables like ‘log_bin_trust_function_creators‘;
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | ON    |
+---------------------------------+-------+
1 row in set (0.00 sec)

分支结构示例

delimiter $$
create function sub_str(str varchar(255),n int)
returns varchar(255)
begin
if isnull(str) then return ‘‘;
elseif char_length(str)<n then return str;
else return left(str,n);
end if;
end$$
delimiter ;

--结果
mysql> select sub_str(‘wozhidaole‘,1);
+-------------------------+
| sub_str(‘wozhidaole‘,1) |
+-------------------------+
| w                       |
+-------------------------+
1 row in set (0.00 sec)

触发器,是一种特殊的存储过程,在特定表执行更新,插入,删除操作时触发,具有更好的数据控制能力,创建语法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_body

示例

delimiter $$
create trigger pp after insert on t1 for each row
begin
insert into t2 values (new.id);
end$$
delimiter ;

删除触发器

mysql> drop trigger pp;
Query OK, 0 rows affected (0.00 sec)

查看所有触发器

mysql> show triggers\G
*************************** 1. row ***************************
             Trigger: pp
               Event: INSERT
               Table: t1
           Statement: begin
insert into t2 values (new.id);
end
              Timing: AFTER
             Created: NULL
            sql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
             Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
1 row in set (0.01 sec)

查看某一个触发器信息

mysql> show create trigger pp\G
*************************** 1. row ***************************
               Trigger: pp
              sql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
SQL Original Statement: CREATE DEFINER=`root`@`localhost` trigger pp after insert on t1 for each row
begin
insert into t2 values (new.id);
end
  character_set_client: utf8
  collation_connection: utf8_general_ci
    Database Collation: utf8_general_ci
1 row in set (0.00 sec)
mysql> select * from information_schema.triggers where trigger_name=‘pp‘\G
*************************** 1. row ***************************
           TRIGGER_CATALOG: def
            TRIGGER_SCHEMA: test
              TRIGGER_NAME: pp
        EVENT_MANIPULATION: INSERT
      EVENT_OBJECT_CATALOG: def
       EVENT_OBJECT_SCHEMA: test
        EVENT_OBJECT_TABLE: t1
              ACTION_ORDER: 0
          ACTION_CONDITION: NULL
          ACTION_STATEMENT: begin
insert into t2 values (new.id);
end
        ACTION_ORIENTATION: ROW
             ACTION_TIMING: AFTER
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
  ACTION_REFERENCE_OLD_ROW: OLD
  ACTION_REFERENCE_NEW_ROW: NEW
                   CREATED: NULL
                  SQL_MODE: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
                   DEFINER: root@localhost
      CHARACTER_SET_CLIENT: utf8
      COLLATION_CONNECTION: utf8_general_ci
        DATABASE_COLLATION: utf8_general_ci
1 row in set (0.09 sec)
时间: 2024-11-03 03:33:25

MySQL学习笔记九:存储过程,存储函数,触发器的相关文章

PL/SQL&amp;存储过程||存储函数&amp;触发器

plsql 有点:交互式  非过程化   数据操纵能力强   自动导航语句简单   调试简单   想率高 声明类型的方式 1.基本类型 2.引用变量 3.记录型变量 基本格式 declare 声明 begin exception end 判断语句 if:..then... else end if: 循环 loop 退出条件   exit when ...; end loop: 光标 cursor ---resltSet 返回多行数据 格式 cursor 表明 oper 打开 fetch 去一行光

Mysql学习笔记(十二)触发器

学习内容: 1.触发器: 什么是触发器?我们什么时候能够使用触发器?   触发器就是用来监听某个表的变化,当这个表发生变化的时候来触发某种操作..比若说两个表是相互关联的,当我们在对其中一个表格进行操作的同时,另一个表内的数据也需要进行某种操作,那么我们就需要建立一个触发器来监听任何一个表发生的变化,当其中一个表的数据发生变化的同时,触发器里的代码块将会对另一个表格进行对数据的某种操作.. 总而言之,触发器一般是使用在表与表之间的,单个的表建立触发器是没有任何的意义的.... 触发器的监听范围:

MySQL学习笔记七:存储引擎

1.MySQL存储引擎的设计采用“插件式”方案,用户可以很方便地选择使用哪种存储引擎,想使用mysql没有提供的引擎时,可以自己安装进去. 查看支持的存储引擎 mysql> show engines\G *************************** 1. row *************************** Engine: FEDERATED Support: NO Comment: Federated MySQL storage engine Transactions: N

MySQL学习笔记(四):存储引擎的选择

一:几种常用存储引擎汇总表 二:如何选择 ? MyISAM:默认的MySQL插件式存储引擎.如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性.并发性要求不是很高,那么选择这个存储引擎是非常适合的.MyISAM是在Web.数据仓储和其他应用环境下最常使用的存储引擎之一. ? InnoDB:用于事务处理应用程序,支持外键.如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询以外,还包括很多的更新.删除操作,那么InnoDB存储引擎应

MySQL学习笔记(2) - MyISAM存储引擎

在5.5版本之前,MyISAM是MySQL默认的存储引擎.MyISAM不支持事务.也不支持外键,其优势是访问速度快,对事务完整性没有要求或者以SELECT.INSERT为主的应用都可以使用这个引擎来创建表.每个MyISAM在磁盘上存储成3个文件,其文件名和表名相同,但扩展名分别是: .frm(存储表的定义) .MYD(MYData,存储数据) .MYI(MYIndex,存储索引) 数据文件和索引文件可以分别存放在不同的目录,平均分布IO,以获得更快的速度.要指定索引文件和数据文件的路径,需要在创

MySQL学习笔记(12)之触发器(trigger)

触发器(trigger) 1.作用:监视某种情况并触发某种操作. 触发器能监视表的增.删.改,进行增.删.改操作. 2.创建触发器语法:(需要提前修改结束符:delimiter 结束符) create trigger trigger_name after/before 增.删.改 on 表名 For each rom Begin SQL语句: End结束符 触发器名称 触发器时间 After和before的区别: After:先完成数据操作,在触发. Before:先于监视的操作,在触发数据的操

我的MYSQL学习笔记(四)——函数

数字函数 1.求余函数MOD(X,Y) MOD(X,Y)返回x被y除后的余数,MOD()对于带有小数部分的数值也起作用,他返回除法运算后的精确余数 2.函数TRUNCATE(X,Y) TRUNCATE(X,Y)返回被舍去至小数点后y位的数字x.若y的值为0,则结果不带有小数点或不带有小数部分. 若y设为负数,则截去(归零)x小数点左边起第y位开始后面所有低位的值. TIPS:ROUND(X,Y)函数在截取值的时候会四舍五入,而TRUNCATE(x,y)直接截取值,并不进行四舍五入 3.HEX(N

Shell 脚本学习笔记九:Shell函数

函数的定义格式: function funName() { action; return xxx; } 1.可以带function fun() 定义,也可以直接fun() 定义,不带任何参数 2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值. return后跟数值n /// 1.没有 return 语句的函数 demoFun() { echo "这是一个Shell函数"; } echo "----- 函数开始执行 -----&quo

MySQL学习笔记(三):常用函数

一:字符串函数 需要注意的几个细节: 1.cancat中有一个字符串为null,则结果为null. 2.left(str,x) 和 right(str,x)中x为null,则不返回任何字符串,不是null. 二:数值函数 注意的几个细节: 1.truncate(x,y) 和 round(x,y) 都能截断,只是round会四舍五入,而truncate不会. 三:日期和时间函数 四:流程函数 五:其他函数