MySQL-存储过程

我们常用的操作数据库语言SQL语句在执行的时候需要要先编译, 然后执行; 而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集, 经编译后存储在数据库中, 用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数, 它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数, 或者封装特定功能时, 存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。可以认为是用来重复执行的一系列SQL语句(类似函数)。

优点: 如果一系列SQL语句, 被用来多次执行, 那么用存储过程是很快的。因为存储过程是预编译的。在首次运行一个存储过程时查询, 优化器对其进行分析优化, 并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化, 速度相对要慢一些。

先讲解变量:

  MySQL中变量以"@"开始 形式为"@变量名" 使用set、select配合":="、"="来进行设置或赋值 比如"set @name='John'", "set @name:='John'", "select @mid:=max(id) from tname"类似来设置变量 set可以用":=", 也可以用"=", 但select只能用":=" 因为select语句中"="表示相等判断

  系统变量: 服务器运行时许多变量可以动态更改,而无需重启服务器,即动态配置。设置用户变量的时候加上GLOBAL等就是设置系统变量 可以使用"set GLOBAL 变量名"或者"set @@global.变量名"来设置系统变量 系统变量对所有客户端有效 只有超级权限的用户才可以设置系统变量 引用的时候只能用@@

  用户变量/会话变量: 基于会话变量实现的,可以暂存值,并传递给同一连接里的下一条sql使用的变量。经常用来向SQL中传值。当客户端连接退出时,变量会被释放。设置用户变量时没有加上GLOBAL等就是设置会话变量 即使用默认的SESSION(LOCAL) 可以使用"set @变量名"、"set SESSION 变量名"、"set @@session.变量名" 是跟客户端绑定的 设置的变量只对连接的客户端有效 客户端关闭后变量消失

  局部变量: 在BEGIN、END语句块之间设置的变量

  局部变量和用户变量区分在于三点:

    1.定义语句不同,用户变量使用set定义,局部变量使用declare定义;

    2.用户变量是以"@"开头的,而局部变量没有这个符号;

    3.作用范围,用户变量作用于本客户端,局部变量作用于本块;

  @@var_name如果不指定global|local|session, 则返回session中的值, 否则返回global的值 实用原则: 普通变量用@, 系统变量用@@

  总结: 变量包括系统变量、会话变量和局部变量(只要记住有这三种类型变量及其区分就行了), 且变量的只只能为单一值(比如count(*)), 不能为查询出来的多条记录

  查询变量的值: "select @name"、"select @@global.GROUP_CONCAT_MAX_LEN"、"select @@GROUP_CONCAT_MAX_LEN"(查询的session的)

  只要不加global 默认都是session

注: BEGIN、END可以认为是函数中的花括号"{"、"}", 以包含函数体或者结构块;

创建:

  CREATE PROCEDURE 存储过程名(参数列表)

  BEGIN

    SQL语句(比如 "SELECT * INTO s FROM USERS;");  #语句以分号结束

  END

  注: 可以用"DELIMITER //"来设置MySQL的语句结束符号 记得改完再改回来

  参数类型有三种IN(输入参数, 在调用存储过程时指定, 相当于PHP的值传递), OUT(输出参数, 可返回, 相当于PHP的引用传值, 不论用户传值与否初始都为NULL), INOUT(输入输出参数)

  

删除:

  DROP PROCEDURE 存储过程名

修改:

  ALTER PROCEDURE 存储过程名(参数列表)

  语句块

查询:

  SHOW CREATE PROCEDURE 数据库名.存储过程名 //查看存储过程的详细

  SHOW PROCEDURES STATUS //查看所有或者某个数据库下的存储过程 后也可以跟where db='数据库名' 指定数据库;

调用:

  CALL 存储过程名(参数列表)

  注: CALL语句可以用声明为OUT或的INOUT参数的参数给它的调用者传回值 存储过程名称后面必须加括号 哪怕该存储过程没有参数传递

注释:

  1.使用"--" 单行注释

  2.使用"/**/" 多行注释

 

DECLARE语句用来声明局部变量, 仅被用在BEGIN, END复合语句里, 且必须在复合语句的开头, 任何其他语句之前 句式为DECLARE variable_name [,variable_name...] datatype [DEFAULT value];

示例: DECLARE l_int int unsigned default 4000000;(跟创建表结构时一样)

SELECT INTO语句来对变量进行赋值 select user, pass into x, y from user; 变量名不能与列名相同!!

存储过程参数:

  参数变量以及里面DECLARE的变量都不用@

MySQL 存储过程参数(in)
MySQL 存储过程 "in" 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible)
MySQL 存储过程参数(out)
MySQL 存储过程 "out" 参数:从存储过程内部传值给调用者 在存储过程内部, 该参数初始赋值为null, 无论调用者调用存储过程时是否给此参数设置值
MySQL 存储过程参数(inout)
MySQL 存储过程 inout 参数跟C语言的引用传递类似 可以从存储过程内部传值给调用者 不同的是:调用者还可以通过 inout 参数传递值给存储过程
总结: 如果仅仅想把数据传给 MySQL 存储过程,那就使用"in" 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用"out" 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用"inout" 类型参数

示例:

  create procedure my_pro(in n int)

    begin

      select @name:=User from user where id=n  limit 1;

    end;

 

  调用:

    set @n=1

    call my_pro(@n);

 

结构语句:

  if vname='John' then

    ...

  else

    ...

  end if;

 

  case vname

  when 0 then

    ...

  when 1 then

    ...

  else

    ...

  end case;

 

  while vname < 6 do

    ...

  end while;

 

字符串类函数:

CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ]) //连接字串
INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0
LCASE (string2 ) //转换成小写
LEFT (string2 ,length ) //从string2中的左边起取length个字符
LENGTH (string ) //string长度
LOAD_FILE (file_name ) //从文件读取内容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置
LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重复count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str
RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比较两字串大小,
SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符,
注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1

 

数学类函数:

ABS (number2 ) //绝对值
BIN (decimal_number ) //十进制转二进制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //进制转换
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小数位数
HEX (DecimalNumber ) //转十六进制
注:HEX()中可传入字符串,则返回其ASC-11码,如HEX('DEF')返回4142143
也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指数
RAND([seed]) //随机数
ROUND (number [,decimals ]) //四舍五入,decimals为小数位数]

 

时间类函数:

ADDTIME (date2 ,time_interval ) //将time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //转换时区
CURRENT_DATE ( ) //当前日期
CURRENT_TIME ( ) //当前时间
CURRENT_TIMESTAMP ( ) //当前时间戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间
DATEDIFF (date1 ,date2 ) //两个日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1为星期天
DAYOFYEAR (date ) //一年中的第几天
EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分
MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串
MAKETIME (hour ,minute ,second ) //生成时间串
MONTHNAME (date ) //英文月份名
NOW ( ) //当前时间
SEC_TO_TIME (seconds ) //秒数转成时间
STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示
TIMEDIFF (datetime1 ,datetime2 ) //两个时间差
TIME_TO_SEC (time ) //时间转秒数]
WEEK (date_time [,start_of_week ]) //第几周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第几天
HOUR(datetime) //小时

 

参考:http://www.blogjava.net/sxyx2008/archive/2009/11/24/303497.html

参考:http://www.jb51.net/article/30825.htm

posted on 2013-09-22 13:01  John_ABC  阅读(339)  评论(0编辑  收藏  举报

导航