IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL8.0 存储过程和函数 -> 正文阅读

[大数据]MySQL8.0 存储过程和函数

PART1. 创建存储过程和函数

存储程序可以分为存储过程和函数。在MySQL中,创建存储过程和函数使用的语句分别是CREATE PROCEDURE 和 CREATE FUNCTION。使用CALL语句来调用存储过程,只能用输出变量返回值。函数可以从语句外调用(引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。

1. 创建存储过程

创建存储过程,需要使用CREATE PROCEDURE语句:

CREATE PROCEDURE sp_name ( [proc_parameter] )
[characteristics ... ] routine_body

CREATE PROCEDURE为用来创建存储函数的关键字;

sp_name为存储过程的名称;

pro_parameter为指定存储过程的参数列表:

[ IN | OUT | INOUT ] param_name type

其中,IN 表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;

param_name表示参数名称;

type表示参数的类型。

characteristics 指定存储过程的特性,有以下取值;

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

2)[NOT] DETERMINISTIC: 指明存储过程执行的结果是否正确。默认为 NOT?DETERMINISTIC。

3){ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }: 指明子程序使用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 代码的开始和结束。

DELIMITER //
CREATE PROCEDURE Proc()
BEGIN
SELECT * FROM fruits;
END // 
DELIMITER;

注意:“DELIMITER // ”语句的作用是将MySQL的结束符设置为//,因为MySQL默认的语句结束符号为分号’;‘。为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER 改变存储过程的结束符,并以 “END //” 结束存储过程。存储过程定义完毕之后再使用 ”DELIMITER;“恢复默认结束符。DELIMITER也可以指定其他符号作为结束符。

注意:当使用 DELIMITER 命令时,应该避免使用反斜杠(’\')字符,因为反斜线是MySQL的转义字符。

2. 创建存储函数

创建存储函数,需要使用CREATE FUNCTION 语句,且用SELECT 来调用:

CREATE FUNCTION func_name ( [func_parameter] )
RETURNS type
[characteristic ... ] routine_body

CREATE FUNCTION 为用来创建存储函数的关键字:func_name 表示存储函数的名称;

func_parameter为存储过程的参数列表:

[ IN | OUT | INOUT ] param_name type

其中,1)IN 表示输入参数,2)OUT表示输出参数,3)INOUT表示既可以输入也可以输出;

4)param_name表示参数名称;

5)type表示参数的类型;

RETURNS type 语句表示函数返回数据的类型。

DELIMITER //
CREATE FUNCTION NameByZip()
RETURNS CHAR(50)
RETURN (SELECT s_name FROM suppliers WHERE s_call= '48075');

DELIMITER;

如果在存储函数中的RETURN 语句返回一个类型不同于函数的RETURNS子句中指定类型的值,返回值将被强制为恰当的类型。但是,如果一个函数返回一个INT值,但是RETURN语句返回一个字符串,从函数返回的值时会报错。

注意:指定参数为IN、OUT或INOUT只对PROCEDURE是合法的。(FUNCTION中总是默认为IN 参数)。RETURNS子句只能对FUNCTION做指定,对函数而言这是强制的。它用来指定函数的返回类型,而且函数体必须包含一个RETURN value语句。

3. 变量的使用

变量可以在子程序中声明并使用,这些变量的作用范围是在BEGIN…END程序中。

1. 定义变量

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

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

2. 为变量赋值

定义变量之后,为变量赋值可以改变变量的默认值。在MySQL中,使用SET语句为变量赋值:

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

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

DECLARE var1, var2, var3 INT;
SET var1 = 10, var2 = 20;
SET var3 = var1 + var2;

在MySQL中,还可以通过SELECT…INTO为一个或多个变量赋值,语法如下:

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

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

#举例
DECLARE fruitname CHAR(50);
DECLARE fruitprice DECIMAL(8,2);
SELECT f_name,f_price INTO fruitname, fruitprice
FROM fruits WHERE f_id = 'a1';

4. 定义条件和处理程序

特定条件需要特定处理。这些条件可以联系到错误以及子程序中的一般流程控制。定义条件是事先定义程序执行过程中遇到的问题,处理程序定义了在遇到这些问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

1. 定义条件

定义条件使用DECLARE语句:

DECLARE condition_name CONDITION FOR [codition_type]
[condition_type]:
SQLSTATE [VALUE] sqlstate_value | mysql_error_code

1)condition_name参数表示条件的名称;

2)condition_type参数表示条件的类型;

3)sqlstate_value和MySQL_error_code都可以表示MySQL的错误,sqlstate_value为长度为5的字符串类型错误代码,MySQL_error_code为数值类型错误代码。例如ERROR 1142(42000)中,sqlstate_value的值是42000,MySQL_error_code的值是1142。

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

//方法一:使用sqlstate_value
DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000';
//方法二:使用mysql_error_code
DECLARE command_not_allowed CONDITION FOR 1148;

2. 定义处理程序

DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
handle_type:
    CONTINUE | EXIT | UNDO
condition_value:
    SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
| mysql_error_code

handler_type 为错误处理方式,参数取3个值:CONTINUE、 EXIT 和 UNDO。

1)CONTINUE 表示遇到错误不处理,继续执行;

2)EXIT表示遇到错误马上退出;

3)UNDO表示遇到错误后撤回之前的操作,MySQL中暂时不支持这样的操作。

condition_value 表示错误类型,可以有以下取值:

1)SQLSTATE[VALUE]sqlstate_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 匹配数值类型错误代码。

sp_statement参数为程序语句段,表示在遇到定义的错误时需要执行的存储过程或函数。

//方法一:捕获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 CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';

//方法四:使用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”信息。

CREATE TABLE t (s1 INT,PRIMARY KEY (s1));
DELIMITER //
CREATE PROCEDURE handlerdemo()
	BEGIN
		DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
        SET @x = 1;
        INSERT INTO t VALUES (1);
        SET @x = 2;
        INSERT INTO t VALUES (1);
        SET @x = 3;
    END;
    //
DELIMITER ;
/*调用存储过程*/
CALL handlerdemo();
/*查看调用过程结果*/
SELECT @x;

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

注意:“@var_name”表示用户变量,使用SET语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其它客户端看到或被使用。当客户端退出时,该客户端连接的所有变量将自动释放。

5. 光标的使用(SQLSERVER里叫游标)

-- end

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:46:17  更:2022-02-09 20:47:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:32:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码