4.mysql中的存储过程

news/2024/12/16 16:57:17/文章来源:https://www.cnblogs.com/shuiyirar/p/18610587

创建存储过程和函数

CREATE[DEFINER = {USER | CURRENT_USER}]  # 定义者是谁PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...] routine_bodyCREATE [DEFINER = {USER | CURRENT_USER}]FUNCTION sp_name ([function_name[,...]])[characteristic ...] routine_bodyproc_parameter:[in | out | inout] param_name typefunc_parameter:param_name typetype:any valid mysql date typecharacteristic:comment 'string'| language sql| [not] deterministic| {contains sql | no sql | read sql data | modifies sql data}| sql security [definer | invoker]routine_body:valid sql routine statement

存储过程创建语句

CREATE[DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...] routine_bodyproc_parameter:[ IN | OUT | INOUT ] param_name typecharacteristic:COMMENT 'string'| LANGUAGE SQL| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }routine_body:Valid SQL routine statement[begin_label:] BEGIN[statement_list]……
END [end_label]

说明:

函数与存储过程最大的区别就是函数调用有返回值,调用存储过程用call语句,而调用函数就直接引用函数名+参数即可

  • Definer和sql security子句指定安全环境

    • Definder是MySQL的特殊的访问控制手段,当数据库当前没有这个用户权限时,执行存储过程可能会报错
    • definer:在执行存储过程前验证definer对应的用户如:cdq@127.0.0.1是否存在,以及是否具有执行存储过程的权限,若没有则报错
    • invoker:在执行存储过程时判断inovker即调用该存储过程的用户是否有相应权限,若没有则报错
  • in out inout只适用于存储过程

    • IN输入参数用于把数值传入到存储过程中;
      • 需要注意变量的生效范围,是局部变量还是全局变量,如果是全局变量,虽然在存储过程中被修改,但任然不会变化
    • OUT输出参数将数值传递到调用者,初始值是NULL;
    • INOUT输入输出参数把数据传入到存储过程,在存储过程中修改之后再传递到调用者
  • Delimiter命令是改变语句的结束符,MySQL默认的结束符为;号,由于procedure和function中 的;号并不代表创建的结束,所以要替换成另外的结束符以便表示创建的结束

  • Rontine_body子句可以包含一个简单的SQL语句,也可以包含多个SQL语句,通过begin…end将这多个SQL语句包含在一起

  • MySQL存储过程和函数中也可以包含类似create和drop等DDL语句

  • Comment子句用来写入对存储过程和函数的注释

  • Language子句用来表示此存储过程和函数的创建语言

  • 存储过程和函数被标注为deterministic表明当输入相同的参数是会返回相同的结果,反之如果是not deterministic则表示相同参数不会是相同结果,默认是not deterministic

delimiter 的用法
delimiter //create function simplefunc(param1 int)returns intbeginupdate students set sex=1 where sid = param1;select count(*) into @a from students where sid > param1;return @a;end;//
  • 相关属性短语只有咨询含义,并不是强制性的约束

    • Contains sql表明此存储过程或函数不包含读或者写数据的语句,这是默认属性
    • NO SQL表示此存储过程或函数不包含SQL语句
    • Reads sql data表示此存储过程包含诸如select的查询数据的语句,但不包含插入或删除数据的语句
    • Modifies sql data表示此存储过程包含插入或删除数据的语句
  • drop procedure / function语句

drop {procedure | function} [if exists] sp_name;

Begin…end复合语句

  • Begin…end语句通常出现在存储过程、函数和触发器中,其中可以包含一个或多个语句,每个语句用;号隔开
[begin_label:]begin[statement_list]end [end_label]
  • 标签label可以加在begin…end语句以及loop, repeat和while语句

  • 语句中通过iterate和leave来控制流程,iterate表示返回指定标签位置,leave表示跳出标签

[begin_label:] begin[statement_list]
end [end_label][begin_label:] loopstatement_list
end loop [end_label][begin_label:] repeatstatement_list
until search_condition
end repeat [end_label][begin_label:] while search_condition dostatement_list
end while [end_label]CREATE PROCEDURE doiterate(IN p1 INT, OUT p2 int) 
• -> BEGIN
• -> label1: LOOP
• -> SET p1 = p1 + 1;
• -> IF p1 < 10 THEN ITERATE label1; END IF;
• -> LEAVE label1;
• -> END LOOP label1;
• -> set p2=p1;
• -> END;
• -> //
• Query OK, 0 rows affected (0.00 sec) • mysql> delimiter ;

declare语句

  • Declare语句通常用来声明本地变量、游标、条件或者handler

  • Declare语句只允许出现在begin … end语句中而且必须出现在第一行

  • Declare的顺序也有要求,通常是先声明本地变量,再是游标,然后是条件和handler

  • 存储过程中的变量

    • 本地变量可以通过declare语句进行声明
    • 声明后的变量可以通过select … into var_list进行赋值,或者通过set语句赋值,或者通过定义游标并使用fetch … into var_list赋值
    • 通过declare声明变量方法:
declare var_name [, var_name] ... type [default value]
    • 使用default指定变量的默认值,如果没有指定默认值则初始值为NULL
    • Type指明该变量的数据类型
    • 声明的变量作用范围为被声明的begin … end语句块之间
    • 声明的变量和被引用的数据表中的字段名要区分开来

存储过程中的变量

delimiter //
CREATE PROCEDURE sp1 (v_sid int) 
BEGINDECLARE xname VARCHAR(5) DEFAULT 'bob';DECLARE xsex INT;SELECT sname, sex INTO xname, xsexFROM students WHERE sid= v_sid; SELECT xname,xsex; 
END;
//
delimiter ;

流程控制语句

  • MySQL支持if,case,iterate,leave,loop,while,repeat语句作为存储过程和函数中的流程控制语句,另外return语句也是函数中的特定流程控制语句
case case_valuewhen when_value then statement_list[when when_value then statement_list] ...[else statement_list]
end casecasewhen search_condition then statement_list[when search_condition then statement_list][else statement_list]
end casedelimiter //
CREATE PROCEDURE exp_case(v_sid int) 
BEGIN
DECLARE v INT DEFAULT 1;
select sex into v from students where sid=v_sid; 
CASE v
WHEN 0 THEN update students set sex=1 where sid=v_sid; 
WHEN 1 THEN update students set sex=0 where sid=v_sid; 
ELSE
update students set sex=-1 where sid=v_sid; • END CASE;
END;
//
delimiter ;delimiter //
CREATE PROCEDURE exp_case2(v_sid int) 
BEGIN
DECLARE v INT DEFAULT 1;
select sex into v from students where sid=v_sid; 
CASE 
WHEN v=0 THEN update students set sex=1 where sid=v_sid; 
WHEN v=1 THEN update students set sex=0 where sid=v_sid; • ELSE
update students set sex=-1 where sid=v_sid; • END CASE;
END;
//
delimiter ;
  • 流程控制语句

if

if search_condition then statement_list[elsif search_condition then statement_list] ...[else statement_list]
end if
  • IF语句中如果search_condition满足true/1的条件,则执行对应的statement_list,否则再判断elseif中的search_condition是否满足true/1的条件,如果都不满足则执行else中的statement_list语句

  • Statement_list中可以包含一个或多个SQL语句

• DELIMITER //
• CREATE FUNCTION SimpleCompare(n INT, m INT)
• RETURNS VARCHAR(20) 
• BEGIN
• DECLARE s VARCHAR(20);
• IF n > m THEN SET s = '>';
• ELSEIF n = m THEN SET s = '=';
• ELSE SET s = '<';
• END IF; 
• SET s = CONCAT(n, ' ', s, ' ', m);
• RETURN s;
• END //
• DELIMITER ;
  • Iterate语句仅出现在loop,repeat,while循环语句中,其含义表示重新开始此循环

iterate

iterate label
  • label表示自定义的标签名

  • Leave语句表明退出指定标签的流程控制语句块

  • 通常会用在begin…end,以及loop,repeat,while的循环语句中

leave label# label表名要退出的标签名• mysql> delimiter //
• mysql> CREATE PROCEDURE doiterate(IN p1 INT, OUT p2 int) • -> BEGIN
• -> label1: LOOP
• -> SET p1 = p1 + 1;
• -> IF p1 < 10 THEN ITERATE label1; END IF;
• -> LEAVE label1;
• -> END LOOP label1;
• -> set p2=p1;
• -> END;
• -> //

流程控制loop语句

  • Loop语句是存储过程或函数中表达循环执行的一种方式
[begin_label:] loopstatement_list
end loop [end_label]
  • 其中的statement_list可以包含一个或多个SQL语句
CREATE PROCEDURE doiterate(p1 INT)
BEGINlabel1: LOOPSET p1 = p1 + 1;IF p1 < 10 THENITERATE label1;END IF;LEAVE label1;END LOOP label1;SET @x = p1;
END; 01

流程控制repeat语句

  • repeat语句是存储过程或者函数中表达循环执行的一种方式
[begin_label]  repeatstatement_list
until search_condition
end repeat [end_label]
  • Repeat语句中statement_list一直重复执行直到search_condition条件满足

  • Statement_list可以包含一个或多个SQL语句

• mysql> delimiter //
• mysql> CREATE PROCEDURE dorepeat(p1 INT)
• -> BEGIN
• -> SET @x = 0;
• -> REPEAT
• -> SET @x = @x + 1;
• -> UNTIL @x > p1 END REPEAT;
• -> END
• -> //

while

  • 语句是存储过程或者函数中表达循环执行的一种方式

  • 当search_condition返回为true时,则循环执行statement_list中的语句,直到search_condition的结果返回为false

  • Statement_list中可以包含一个或多个SQL语句

[begin_list] while search_condition dostatement_list
end while [end_label]create procedure  pro1()
begindeclare std_id int default 1;
while std_id > 10 doinsert into student values(std_id,'milk',1,1);set std_id = std_id +1;
end while;
end ;

return

  • 语句用在函数中,用来终结函数的执行过程并将指定值返回给调用者
return expr
  • 在函数中必须要有至少一个return语句,当有多个return语句时则表名函数有多种退出方式
• delimiter //
• create function doreturn()
• returns int
• begin
• select sex into @a from students where sid=1;
• if @a=1 then return 1;
• elseif @a=0 then return 0;
• else return 999;
• end if;
• end;
• //
• delimiter ;

游标

  • cursor游标用来声明一个数据集

  • 游标的声明必须在变量和条件声明之后,在handle声明之前

声明游标

  • Cursor declare语句用来声明一个游标和指定游标对应的数据集合,通常数据集合是一个select语句
declare cursor_name cursor for select_statement# select_statement代表一个select语句

打开游标

  • Open cursor语句用来打开一个之前已经声明好的游标
open cursor_name

读取游标

  • Cursor fetch语句用来获取游标指定数据集的下一行数据并将各个字段值赋予后面的变量
fetch [[next] from ] cursor_name into var_name [, var_name] ...
  • 数据集中的字段需要和into语句中定义的变量一一对应

  • 数据集中的数据都fetch完之后,则返回not found

关闭游标

CLOSE cursor_name ;

declare condition语句(异常处理)

  • Declare condition语句命名特定的错误条件,而该特定错误可以在declare…handler中指定处理方法
declare condition_name condition for condition_valuecondition_value:mysql_error_code| sqlstate [value] sqlstate_value
  • Condition_value指定特定的错误条件,可以有以下两种形式

    • Mysql_err_code表示MySQL error code的整数
    • SQLSTATE sqlstate_value表示MySQL中用5位字符串表达的语句状态
  • 在MySQL中1051error code表示的是unknown table的错误,如果要对这个错误做特殊处理,可以用三种种方法:

• DECLARE CONTINUE HANDLER FOR 1051
• BEGIN
• -- body of handler
• END;• DECLARE no_such_table CONDITION FOR 1051; 
• DECLARE CONTINUE HANDLER FOR no_such_table
• BEGIN
• -- body of handler
• END; 
• DECLARE no_such_table CONDITION FOR SQLSTATE '42S02';
• DECLARE CONTINUE HANDLER FOR no_such_table
• BEGIN
• -- body of handler
• END;

declare handler语句(异常处理)

  • Declare handler语句用来声明一个handler来处理一个或多个特殊条件,当其中的某个条件满足时则触发其中的statement语句执行

  • Statement可以是一个简单SQL语句,也可以是begin…end组成的多个语句

declare handle_action handlerfor condition_value [,condition_value] ...statementhandler_action:continue| exit| undocondition_value:mysql_error_code| sqlstate [value] sqlstate_value| condition_name| sqlwarning| not found| sqlexception
  • Handler_action子句声明当执行完statement语句之后应该怎么办

    • Continue代表继续执行该存储过程或函数
    • Exit代表退出声明此handler的begin…end语句块
    • Undo参数已经不支持
  • condition_value的值有以下几种

    • Mysql_err_code表示MySQL error code的整数
    • SQLSTATE sqlstate_value表示MySQL中用5位字符串表达的语句状态
    • Condition_name表示之前在declare…condition语句中声明的名字
    • SQLWARNING表示所有的警告信息,即SQLSTATE中01打头的所有错误
    • NOT FOUND表示查完或者查不到数据,即SQLSTATE中02打头的所有错误
    • SQLEXCEPTION表示所有的错误信息
• DECLARE CONTINUE HANDLER FOR 1051
• BEGIN
• -- body of handler
• END;
• 
• DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02'
• BEGIN
• -- body of handler
• END;
• 
• DECLARE CONTINUE HANDLER FOR SQLWARNING
• BEGIN
• -- body of handler
• END;
• 
• DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
• BEGIN
• -- body of handler
• END;
  • 当condition发生但没有声明handler时,则存储过程和函数依照如下规则处理

    • 发生SQLEXCEPTION错误,则执行exit退出
    • 发生SQLWARNING警告,则执行contine继续执行
    • 发生NOT FOUND情况,则执行continue继续执行
• 比如SQLSTATE ‘23000’表示主键冲突错误
• mysql> CREATE TABLE t (s1 INT, PRIMARY KEY (s1));
• Query OK, 0 rows affected (0.00 sec) 
• mysql> delimiter //
• mysql> CREATE PROCEDURE handlerdemo ()
• -> BEGIN
• -> DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
• -> SET @x = 1;
• -> INSERT INTO test.t VALUES (1);
• -> SET @x = 2;
• -> INSERT INTO test.t VALUES (1);
• -> SET @x = 3;
• -> END;
• -> //CREATE PROCEDURE curdemo()
• BEGIN
• DECLARE done INT DEFAULT FALSE;
• DECLARE a CHAR(16);
• DECLARE b, c INT;
• DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
• DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
• DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
• OPEN cur1;
• OPEN cur2;
• read_loop: LOOP
• FETCH cur1 INTO a, b;
• FETCH cur2 INTO c;
• IF done THEN
• LEAVE read_loop; • END IF;
• IF b < c THEN
• INSERT INTO test.t3 VALUES (a,b);
• ELSE
• INSERT INTO test.t3 VALUES (a,c);
• END IF;
• END LOOP;
• CLOSE cur1;
• CLOSE cur2;
• END;
0

mysql中prepare语句的使用方法

SELECT * 
FROM products 
WHERE productCode = ?;

MySQL PREPARE 语句用法

为了使用MySQL预处理语句,您需要使用其他三个MySQL语句,如下所示:

  • PREPARE - 准备要执行的语句。

  • EXECUTE - 执行由PREPARE语句准备的预准备语句。

  • DEALLOCATE PREPARE - 发布准备好的声明。

下图说明了如何使用预准备语句:

img

PREPARE stmt1 FROM 'SELECT productCode, productNameFROM productsWHERE productCode = ?';SET @pc = 'S10_1678';
EXECUTE stmt1 USING @pc;DEALLOCATE PREPARE stmt1;

首先,我们使用PREPARE语句准备执行语句。我们使用 SELECT语句根据指定的产品代码查询products表中的产品数据 。我们使用问号(?)作为产品代码的占位符。

接下来,我们声明了一个产品代码变量 @pc并将其值设置为S10_1678

然后,我们使用EXECUTE语句用产品代码变量执行预准备语句@pc

最后,我们用它 DEALLOCATE PREPARE来发布准备好的声明。

​ 类似于python中%的一个用法,对字符串进行占位,使用按照需求进行传值

mysql中如何查询存储过程相关语句

 SHOW PROCEDURE STATUS LIKE 存储过程名;# 或者通过select语句获取SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME=存储过程名;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/853839.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

印象笔记使用

vscode安装插件登录印象笔记,开通token点击插件页面的设置填写url和tokenctrl + shift + pever new - 新建笔记 ever open - 打开笔记 ever search - 搜索笔记 ever publish - 发布笔记 ever sync - 同步笔记新建笔记下载安装windows客户端,功能比网页端更全面客户端才能导出…

(BIBM-2024) 用于药物相互作用预测的可解释多视图注意网络

用于药物相互作用预测的可解释多视图注意网络 论文标题: Interpretable multi-view attention network for drug-drug interaction prediction 论文地址: https://ieeexplore.ieee.org/document/10385757 论文期刊: BIBM 2024 摘要 药物间相互作用(DDI)在药物发现中发挥着越来…

Volatility取证工具安装教程

linux安装vol2.6 1.准备工作 准备一台虚拟机,拥有python2版本(虚拟机以kali为例) 准备Volatility2.6安装包 volatilityfoundation/volatility: An advanced memory forensics framework 准备反编译库安装包 vext01/distorm3: distorm3 2.安装步骤详解(全程在root用户下操作…

[React]AntDesign 4.x 汉化

antd汉化,适用于4.x转载自:https://blog.csdn.net/weixin_43013802/article/details/132870349全局汉化,在main.ts中引入下面代码:import{ ConfigProvider }fromantd import locale from antd/locale/zh_CN; import dayjs/locale/zh-cn;ReactDOM.createRoot(document.getEl…

线性回归(linear regression)

其实线性回归不过就是在做两件事,画一条线并判断这条线到各个点的距离。 如下图:其中这条线便是距离各个点距离总和最小的直线。也就是e+u+w+b+a总和在直线为这个情况下最小。但是什么时候这条线是我们需要的线呢?-- 线到各个点最短的时候便是。 我们先理解一下什么是凹函数…

数据库安全性与权限管理

title: 数据库安全性与权限管理 date: 2024/12/16 updated: 2024/12/16 author: cmdragon excerpt: 数据库安全性与权限管理是保护数据不被未授权访问和操控的关键所在。通过实施有效的安全措施和细粒度的权限控制,可以确保数据库的完整性、机密性和可用性。 categories:前端…

数据整合+团队协作,电商选品效率提升100%!

选品快准狠!在线协同助力电商团队做出更聪明的决策 在电商行业,“选品”决定成败。无论是发现爆款、避开雷区,还是追踪最新趋势,每一个决策都离不开团队协作与信息整合。然而,大量的电商团队仍旧面临以下常见问题: - 决策过程拉长,错失销售机会。 - 数据不统一,选品思路…

xshell类似的工具,还有哪些Xshell类似的工具呢

Xshell是一款功能强大的远程连接工具,广泛用于SSH、Telnet和Rlogin协议,帮助用户轻松连接和管理远程服务器。然而,Xshell并不是唯一的远程连接工具,市面上还有其他一些类似的工具,能够提供类似甚至更丰富的功能。那么,除了Xshell,还有哪些类似的远程连接工具呢?以下将为…

SOA整车电子电气仿真测试解决方案

经纬恒润TESTBASE 硬件在环(HIL)仿真测试平台可以为SOA电子电气系统提供高效自动化测试的一站式解决方案,为SOA车型电子电气系统的测试验证提供有力保障。概述软件定义汽车时代,汽车电子软件的功能数量和复杂度与传统汽车相比有了爆炸式增长,并且还在不断提升。以中央+区域…

线程和进程

线程 什么是线程和进程? 何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进…

FastExcel 合并单元格(相当的行数据,进行合并)

目录需求思路实现Excel导出单元格全量合并策略日期格式转换接口代码ServiceDTO 使用FastExcel数据导出:官网: https://idev.cn/fastexcel/zh-CN 需求 信用代码、填报人,唯一时,将:信用代码、单位名称、填报人,进行 row 合并,并垂直居中对齐思路 这边不需要做列合并,所…

街面环卫算法视频分析服务器浅析智能视频监控在智慧城市的应用与趋向

在数字化浪潮的推动下,智慧城市的建设已成为全球范围内城市发展的重要趋势。智慧城市不仅仅是技术的集合,它更是一个系统工程,涉及到城市管理的各个方面,旨在通过高科技手段提升城市的运行效率和居民的生活质量。 其中,智能视频监控技术作为智慧城市建设的关键组成部分,正…