使用CALL语句来调用存储过程,存储过程也可以调用其他存储过程
函数可以从语句外调用,能返回标量值
创建存储过程
语法
CREATE PROCEDURE sp_name ([ proc_parameter ]) [ characteristics..] routine_body
proc_parameter指定存储过程的参数列表,列表形式如下:
[IN|OUT|INOUT] param_name type
其中in表示输入参数,out表示输出参数,inout表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型
该类型可以是MYSQL数据库中的任意类型
有以下取值:
characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string' routine_body: Valid SQL procedure statement or statements
LANGUAGE SQL :说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL,SQL是LANGUAGE特性的唯一值
[NOT] DETERMINISTIC :指明存储过程执行的结果是否正确。DETERMINISTIC 表示结果是确定的。每次执行存储过程时,相同的输入会得到
相同的输出。
[NOT] DETERMINISTIC 表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为[NOT] DETERMINISTIC
CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA:指明子程序使用SQL语句的限制。
CONTAINS SQL表明子程序包含SQL语句,但是不包含读写数据的语句;
NO SQL表明子程序不包含SQL语句;
READS SQL DATA:说明子程序包含读数据的语句;
MODIFIES SQL DATA表明子程序包含写数据的语句。
默认情况下,系统会指定为CONTAINS SQL
SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。DEFINER 表示只有定义者才能执行
INVOKER 表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER
COMMENT 'string' :注释信息,可以用来描述存储过程或函数
routine_body是SQL代码的内容,可以用BEGIN...END来表示SQL代码的开始和结束。
下面的语句创建一个查询t1表全部数据的存储过程
DROP PROCEDURE IF EXISTS Proc; DELIMITER // CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3; END// DELIMITER ; CALL Proc();
t3表是我们上一节创建的表
这里的逻辑是
1、先判断是否有Proc() 这个存储过程,有就drop掉
2、创建Proc() 存储过程
3、执行Proc() 存储过程
注意:“DELIMITER //”语句的作用是将MYSQL的结束符设置为//,因为MYSQL默认的语句结束符为分号;,为了避免与存储过程
中SQL语句结束符相冲突,需要使用DELIMITER 改变存储过程的结束符,并以“END//”结束存储过程。
存储过程定义完毕之后再使用DELIMITER ;恢复默认结束符。DELIMITER 也可以指定其他符号为结束符!!!!!!!!!
如果你是这样写的话,就会得到如下错误,初学者很容易犯这个错误,包括本人
CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3; END Query: CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3 Error Code: 1064 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 '' at line 3 Execution Time : 0 sec Transfer Time : 0 sec Total Time : 0.001 sec --------------------------------------------------- Query: END Error Code: 1064
创建名为CountProc的存储过程,代码如下:
DROP PROCEDURE IF EXISTS CountProc; DELIMITER // CREATE PROCEDURE CountProc(OUT param1 INT) BEGIN SELECT COUNT(*) INTO param1 FROM s_visit_log; END// DELIMITER ; CALL CountProc(@aaa); SELECT @aaa;
上面代码的作用是创建一个获取t3表记录数的存储过程,名称是CountProc,
COUNT(*)计算后把结果放入参数param1中。
注意:当使用DELIMITER命令时,应该避免使用反斜杠(\)字符,因为反斜杠是MYSQL的转义字符!!!
存储函数
创建存储函数,需要使用CREATE FUNCTION语句,基本语法如下:
CREATE FUNCTION func_name([func_parameter]) RETURNS TYPE [characteristics...] routine_body
CREATE FUNCTION为用来创建存储函数的关键字;func_name表示存储函数的名称
func_parameter为存储函数的参数列表,参数列表如下
[IN|OUT|INOUT]PARAM_NAMETYPE
其中,IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;
param_name表示参数名称;type表示参数类型,该类型可以是MYSQL数据库中的任意类型
RETURNS TYPE语句表示函数返回数据的类型;characteristics:指定存储函数的特性,取值与创建存储过程时相同
创建存储函数,名称为NameByT,该函数返回SELECT语句的查询结果,数值类型为字符串型
DELIMITER // CREATE FUNCTION NameByT() RETURNS CHAR(50) RETURN (SELECT NAME FROM t3 WHERE id=2); // DELIMITER ;
注意:RETURNS CHAR(50)数据类型的时候,RETURNS 是有S的,而RETURN (SELECT NAME FROM t3 WHERE id=2)的时候RETURN是没有S的
所以有时候大家可能觉得MYSQL很烦,谁不知是自己写错了
这里有一个方法,就是利用SQLYOG的代码格式化功能,选中要格式化的代码,然后按F12,如果能格式化,证明你的代码没有问题,如果不能格式化
证明你写的代码有问题!!!
不加s的话就会出现语法错误了
Query: create function NameByT() return char(50) return (select name from t3 where id=2) Error Code: 1064 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 'return char(50) return (select name from t3 where id=2)' at line 2 Execution Time : 0 sec Transfer Time : 0 sec Total Time : 0.003 sec -----------------------------
调用函数
SELECT nameByT()
如果在存储函数中的RETURN语句返回一个类型不同于函数的RETURNS子句中指定类型的值,返回值将被强制转换为恰当的类型。
例如,如果一个函数返回一个SET或ENUM值,但是RETURN语句返回一个整数,对于SET成员集的相应ENUM成员,从函数返回的值
是字符串。
指定参数为IN、OUT、INOUT只对PROCEDURE是合法的。
(FUNCTION中总是默认是IN参数)RETURNS子句对FUNCTION做指定,对函数而言这是强制的。
他用来指定函数的返回类型,而且函数体必须包含一个RETURN value语句
变量的使用
变量可以在子程序中声明并使用,这些变量的作用范围是在BEGIN...END程序中
1、定义变量
在存储过程中定义变量
DECLARE var_name[,varname]...date_type[DEFAULT VALUE];
var_name为局部变量的名称。DEFAULT VALUE子句给变量提供一个默认值。值除了可以被声明为一个常数外,还可以被指定为一个表达式。
如果没有DEFAULT子句,初始值为NULL
DECLARE MYPARAM INT DEFAULT 100;
2、为变量赋值
定义变量之后,为变量赋值可以改变变量的默认值,MYSQL中使用SET语句为变量赋值
SET var_name=expr[,var_name=expr]...
在存储过程中的SET语句是一般SET语句的扩展版本。
被SET的变量可能是子程序内的变量,或者是全局服务器变量,如系统变量或者用户变量
他运行SET a=x,b=y,....
声明3个变量,分别为var1,var2和var3