美文网首页
存储过程的创建

存储过程的创建

作者: 三斤耳朵 | 来源:发表于2017-11-29 17:00 被阅读567次

        在开发过程中经常会遇到重复使用某一功能的情况,为此,MySQL引入了存储过程。存储过程就是一条或多条语句的集合,当对数据库进行一系列复杂操作时,存储过程可以将这些复杂操作封装成一个代码块,以便重复使用,大大减少数据库开发人员的工作量。本节将针对如何创建存储过程及创建存储过程时需要用到的变量、光标、流程控制等进行详细的讲解。

在mysql下

mysql> CREATE PROCEDURE myproc() BEGIN END;

出现:

Error Code: 1655

Cannot create stored routine `myproc`. Check warnings

解決方式:

修改my.ini的sql-mode(sql-mode="ANSI,TRADITIONAL"),重启MySQL,即可。

原始资料来源:http://bugs.mysql.com/bug.php?id=34794


创建存储过程

        想要使用存储过程,首先要创建一个存储过程。创建存储过程,需要使用CREATE PROCEDURE语句,创建存储过程的基本语法格式如下。

CREATE PROCEDURE sp_name([proc_parameter])

[characteristics ...] routine_body

        上述语法格式中,CREATE PROCEDURE为用来创建存储过程的关键字;sp_name为存储过程的名称;proc_parameter 为指定存储过程的参数列表,该参数列表的形式如下:

[IN|OUT|INOUT] param_name type

        上述参数列表的形式中,IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name表示参数名称;type表示参数类型,它可以是MySQL数据库中的任意类型。

        在创建存储过程的语法格式中,characteristics用于指定存储过程的特性,它的取值说明具体如下。

        (1)LANGUAGE SQL :说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL,SQL是LANGUAGE的唯一值。

        (2)[NOT] DETERMINISTIC:指名存储过程的结果是否确定。DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出;NOT DETERMINISTIC 表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为NOT DETERMINISTIC。

        (3){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。

        (4)SQL SECURITY {DEFINER | INVOKER}:指明谁有权限来执行。DEFINER表示只有定义者才能执行。INVOKER表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER。

        (5)COMMENT'string':注释信息,可以用来描述存储过程。

        routine_body是SQL代码的内容,可以用BEGIN...END来表示SQL代码的开始和结束。

        接下来通过一个案例演示一下存储过程的创建,首先在数据库chapter06中创建表student,创建student表的SQL语句如下所示:

CREATE TABLE student(

        id INT(3) PRIMARY KEY AUTO_INCREMENT ,

        name VARCHAR(20) NOT NULL , 

        grade FLOAT,

        gender CHAR(2)

);

        执行上述SQL语句创建student表,然后使用INSERT语句向student表中插入4条记录,INSERT语句如下所示:

INSERT INTO student (name , grade , gender) 

VALUES ('tom' , 60 , '男') , ('jack' , 70 , '男') ,('rose' , 90 , '女') ,('lucy' , 100 , '女') ;


例:创建一个查看student表的储存过程,其创建语句如下:

CREATE PROCEDURE Proc()

BEGIN

SELECT * FROM student;

END;

上述代码创建了一个存储过程Proc,每次调用这个存储过程的时候都会执行SELECT语句查看表的内容,代码的执行过程如下:

DELIMITER //

CREATE PROCEDURE Proc()

BEGIN

SELECT * FROM student;

END //

DELIMITER ;

在上述执行过程中,“DELIMITER //”语句的作用是将MySQL的结束符设置为//,因为MySQL默认的语句结束符号为分号“;”,为了避免于存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符,并以“END //”结束存储过程。存储过程定义完毕后再使用“DELIMITER ;”恢复默认结束符。DELIMITER 也可以指定其他符号作为结束符。需要格外注意的是,DELIMITER 与要设定的结束符之间一定要有一个空格,否则设定无效。


变量的使用

在编写存储过程时,有时会需要使用变量保存数据处理过程中的值。在MySQL中,变量可以在子程序中声明并使用,这些变量的作用范围在BEGIN...END程序中,接下来将针对变量的定义和赋值进行详细的讲解。

想要在存储过程中使用变量,首先需要定义变量。在存储过程中使用DECLARE语句定义变量,具体语法格式如下:

DECLARE var_name [,varname] ... data_type[DEFAULT value];

上述语法格式中,var_name为局部变量的名称。DAFAULT value子句给变量提供一个默认值。该值除了可以被声明为一个常数之外,还可以被指定一个表达式。如果没有DAFAULT子句,变量的初始值为NULL。

接下来定义一个名称为myvariable的变量,类型为INT类型,默认值为100,示例代码如下:

DACLARE myvariable INT DEFAULT 100;

定义变量之后,为变量赋值可以改变变量的默认值,MySQL中使用SET语句为变量赋值,语法格式如下:

SET var_name = expr[ , var_name = expr ]...;

在存储过程中的SET语句是一般SET语句的扩展版本。被参考变量可能是子程序内声明的变量,或者是全局服务器变量,如系统变量或者用户变量。

在存储过程中的SET语句作为预先存在的SET语法的一部分来实现。这允许SET a = x , b = y , ...这样的扩展语法。其中不同的变量类型(局域声明变量及全局变量)可以被混合起来。这也允许把局部变量和一些只对系统变量有意义的选项合并起来。

接下来声明三个变量,分别为var1、var2、var3,数据类型为INT,使用SET为变量赋值,示例代码如下:

DECLARE var1,var2,var3 INT;

SET var1 = 10, var2 = 20;

SET var3 = var1 + var2;

除了可以使用SET语句为变量赋值外,MySQL中还可以通过SELECT...INTO为一个或多个变量赋值,该语句可以把选定的列直接存储到对应位置的变量。使用SELECT...INTO的具体语法格式如下:

SELECT col_name [...] INTO var_name[...] table_expr;

在上述语法格式中,col_name表示字段名称;var_name表示定义的变量名称;table_expr表示查询条件表达式,包括表名称和WHERE子句。


例:声明变量s_grade和s_gender,通过SELECT...INTO语句查询指定记录并为变量赋值,具体代码如下:

DELIMITER //

CREATE PROCEDURE Proc1()

BEGIN

DECLARE s_grade FLOAT;

DECLARE s_gender CHAR(2);

SELECT grade , gender INTO s_grade , s_gender

FROM student WHERE name = 'rose';

END //

DELIMITER ;

上述语句将student表中name 为 rose 的同学的成绩和性别分别存入到了变量s_grade和s_gender中。至此有关变量的使用的内容便讲解完了。


定义条件和处理程序

在实际开发中,经常需要对特定的条件进行处理,这些条件可以联系到错误yi'j子程序中的一般流程控制。定义条件是事先定义程序执行过程中遇到的问题,处理程序定义了在遇到这些问题时应当采取的处理方式,并且保证存储过程在遇到警告或者错误时能继续执行。接下来将针对定义条件和处理程序进行详细的讲解。

定义条件

在编写存储过程时,定义条件使用DECLARE语句,语法格式如下:

DECLARE  condition_name CONDITION FOR [condition_type];

// condition_type的两种形式

[condition_type]:

SQLSTATE [VALUE] sqlstate_value | mysql_error_code

上述语法格式中,condition_name表示所定义的条件的名称;condition_type表示条件的类型;sqlstate_value 和 mysql_error_code都可以表示MySQL的错误,sqlstate_value是长度为5的字符串类型错误代码,mysql_error_code为数值类型的错误代码。use mmm; 例如:ERROR1049(42000)中,sqlstate_value的值是42000,mysql_error_code的值是1049。

上述语法格式指定了需要特殊处理的条件。它将一个名字和指定的错误条件关联起来。这个名字可以随后被用在定义处理程序的DECLARE HANDLER语句中。

【例6-4】定义“ERROR1148(42000)”错误,名称为command_not_allowed。可以用两种不同的方法来定义,具体代码如下:

//方法一:使用sqlstate_value

DECLARE command_not_allowed CONDITION FOR SQLSTATE'42000';

//方法二:使用mysql_error_code

DECLARE command_not_allowed CONDITION FOR 1148;

定义处理程序

定义完条件后,还需要定义针对此条件的处理程序。MySQL中用DECLARE语句定义处理程序,具体语法格式如下:

DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement

handler_type:

    CONTINUE | EXIT | UNDO

condition_value:

    |condition_name

    |SQLWARNING

    |NOT FOUND

    |SQLEXCEPTION

    |mysql_error_code

上述语法格式中,handler_type为错误处理方式,参数取三个值:CONTINUE、EXIT和UNDO。CONTINUE表示遇到错误不处理,继续执行;EXIT表示遇到错误马上退出;UNDO表示遇到错误后撤回之前的操作,MySQL中暂时不支持这样的操作sp_statement参数为程序语句段,表示在遇到定义的错误时,需要执行的存储过程;condition_value表示错误类型,可以有以下取值。

(1)SQLSTATE[VALUE]sqlstste_value包含5个字符的字符串错误值。

(2)condition_name表示DECLARE CONDITION定义的错误条件名称。

(3)SQLWARNING匹配所有以01开头的SQLSTATE错误代码。

(4)NOT FOUND匹配所有以02开头的SQLSTATE错误代码。

(5)SQLEXCEPTION匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码。

(6)mysql_error_code匹配数值类型错误代码。

【例6-5】定义处理程序的几种方式,具体代码如下:

上述代码中演示了6种定义处理程序的方法。接下来将分别进行分析讲解,具体如下:

//方法一:捕获sqlstate_value

DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='NO_SUCH_TABLE';

//方法二:捕获mysql_error_code

DECLARE CONTINUE HANDLER FOR 1146 SET @info='NO_SUCH_TABLE';

//方法三:先定义条件,然后调用

DECLARE no_such_table CONTINUE FOR 1146

DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info='ERROR';

//方法四:使用SQLWARNING

DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';

//方法五:使用NOT FOUND

DECLARE EXIT HANDLER FOR NOT FOUND SET @info='NO_SUCH_TABLE';

//方法六:使用SQLEXCEPTION

DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';

第一种方法是捕获sqlstate_value值。如果遇到sqlstate_value为“42S02”,则执行CONTINUE操作,并且输出“NO_SUCH_TABLE”信息。

第二种方法是捕获mysql_error_code值,如果遇到mysql_error_code值为1146,则执行CONTINUE操作,并且输出“NO_SUCH_TABLE”信息。

第三种方法是先定义条件,然后再调用条件。这里先定义no_such_table条件,遇到1146错误就执行CONTINUE操作。

第四种方法是使用SQLWARNING,SQLWARNING捕获所有以01开头的sqlstate_value值,然后执行EXIT操作,并且输出“ERROR”信息。

第五种方法是NOT FOUND,NOT FOUND捕获所有以02开头的sqlstate_value值,然后执行EXIT操作,并且输出“NO_SUCH_TABLE”信息。

第六种方法是SQLEXCEPTION,SQLEXCEPTION捕获所有没有被SQLWARNING或NOT FOUND捕获的sqlstate_value值,然后执行EXIT操作,并且输出“ERROR”信息。

【例6-6】定义条件和处理程序,具体执行过程如下:

编辑过程 调用过程

@x是一个用户变量,执行@x等于3,这表明MySQL被执行到程序的末尾。如果没有“DECLARE CONTINUE HANDLER FOR SQLSTATE‘23000’SET @x2=1;”这句代码,第二个INSERT会因PRIMARY KEY强调而失败之后,MySQL可能已经采取默认(EXIT)路径,并且SELECT@x会返回2。

需要注意的是,“@var_name”表示用户变量,使用SET语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或使用。当客户端退出时,该客户连接的所有变量将自动释放。上述案例中存储过程的调用和查询会在后面章节中进行详细的讲解,这里读者只需了解即可。

光标的使用

在编写存储过程中,查询语句可能会返回多条记录,如果数据量非常大,则需要使用光标来逐条读取查询结果集中的记录。光标是一种用于轻松处理多行数据的机制。接下来将针对光标的声明、使用和关闭进行详细的讲解。

光标的声明

想要使用光标处理结果集中的数据,需要先声明光标。光标必须声明在声明变量、条件之后,声明处理程序之前。MySQL中使用DECLARE关键字来声明光标,声明光标的具体语法格式如下:

DECLARE cursor_name CURSOR FOR select_statement

在上述语法格式中,cursor_name表示光标的名称;select_statement表示SELECT语句的内容,返回一个用于创建光标的结果集。

接下来声明一个名为cursor_student的光标,示例代码如下:

DECLARE cursor_student CURSOR FOR select s_name , s_gender FROM student;

通过上面的代码,已经成功声明了一个名为cursor_student的光标。

光标的使用

声明完光标后就可以使用光标了,使用光标之前首先要打开光标。MySQL中打开和使用光标的语法格式如下:

OPEN cursor_name

FETCH cursor_name INTO var_name [ ,var_name ]...

在上述语法格式中,cursor_name表示参数的名称;var_name表示将光标中的SELECT语句查询出来的信息存入该参数中,需要注意的是,var_name必须在声明光标之前就定义好。

使用名称为cursor_student的光标。将查询出来的信息存入s_name和s_gender中,示例代码如下:

FETCH cursor_student INTO s_name , s_gender;

光标的关闭

使用完光标后要将光标关闭,关闭光标的语法格式如下:

CLOSE cursor_name

值得一提的是,如果没有明确地关闭光标,它会在其声明的复合语句的末尾被关闭。

演示效果

相关文章

  • Mysql存储过程

    阅读目录:MySQL存储过程_创建-调用-参数 存储过程:SQL中的“脚本” 创建存储过程 调用存储过程 存储过程...

  • MySQL批量添加数据

    创建存储过程 执行存储过程 删除存储过程

  • MySQL语法模板 SQL语句:函数、存储过程

    创建函数 创建存储过程 修改函数 修改存储过程 调用 删除函数 删除存储过程

  • 8、存储过程

    8、存储过程 8.1、删除存储过程 8.2、创建存储过程 8.3、创建使用局部变量的存储过程 [^]: 局部变量 ...

  • 创建存储过程

  • SQL Server基础之存储过程

    阅读目录 一:存储过程概述 二:存储过程分类 三:创建存储过程 1.创建无参存储过程 2.修改存储过程 3.删除存...

  • mysql-存储过程

    创建无参数的存储过程 调用无参数存储过程 删除存储过程 创建带有IN类型的存储过程 修改结束标识符为// 调用带有...

  • 存储过程自动创建表分区(按时间)

    存储过程 参数说明 创建测试表 调用存储过程创建分区

  • [SQL] T-SQL: 存储过程

    1. 创建和修改存储过程 (1)创建 (2)修改 2. 存储过程的输入输出参数,返回值 (1)创建存储过程 (...

  • 存储过程的创建

    在开发过程中经常会遇到重复使用某一功能的情况,为此,MySQL引入了存储过程。存储过程就是一条或多条语句的集合,当...

网友评论

      本文标题:存储过程的创建

      本文链接:https://www.haomeiwen.com/subject/pxfpbxtx.html