mysql使用--存储程序

1.概述
存储程序可以封装一些语句,为用户提供一种简单的方式来调用这个存储程序,从而间接执行其封装的语句。
根据调用方式的不同,可把存储程序分为存储例程、触发器、事件几种类型。其中,存储例程又可被细分为存储函数和存储过程。

2.用户自定义变量
MYSQL中,可通过SET语句来自定义一些自己的变量。
如:SET @a = 1;
在我们的自定义变量前面必须加一个@符号。
在使用SET语句时,如变量名前没有加@符号,则MYSQL会把这个变量当作系统变量来对待。
之后想查看这个变量的值,使用SELECT @变量名;
如:SELECT @a;
同一个变量也可存储不同类型的值。如,再把一个字符串赋给变量a。
如:SET @a = ‘哈哈哈’;
除了把一个常量赋给一个变量,也可把一个变量赋给另一个变量。
如:SET @b = @a;
变量a,b是独立的。此后a改变不会影响b。

当某个查询的结果集是一行一列时,可将查询结果集赋给变量。
如:SET @a = (SELECT m1 FROM t1 LIMIT 1);
也可用INTO子句完成类似功能。
如:SELECT n1 FROM t1 LIMIT 1 INTO @b;效果等价于SET @b = (SELECT n1 FROM t1 LIMIT 1);

当某个查询的结果集是一行多列。如想将结果集中各列赋值给不同的变量,不能用SET,只能用INTO。
如:SELECT m1, n1 FROM t1 LIMIT 1 INTO @a, @b;

3.存储函数
存储程序可以分为存储例程,触发器,事件几种类型。
存储例程需我们去手动调用,触发器和事件都是MySQL服务器在特定条件下自己调用的。
存储例程又可分为存储函数,存储过程。

3.1.创建存储函数
存储函数是一种函数,在函数定义中书写MySQL语句。

在MySQL中定义存储函数的语句如下:

CREATE FUNCTION 存储函数名称([参数列表])
RETURNS 返回值类型
BEGIN函数体内容
END

定义一个存储函数时,需指定存储函数名称,参数列表,返回值类型及函数体内容。
如该函数不需参数,则参数列表可省略。
函数体内容被包裹在BEGIN … END中,可包括一条或多条语句,每条语句都要以分号(;)结尾。
上述语句中空格,换行也可略去。不会影响含义。

实例:

CREATE FUNCTION avg_score(s VARCHAR(100))
RETURNS DOUBLE
BEGINRETURN (SELECT AVG(score) FROM student_score WHERE subject = s);
END

由于MySQL默认将;视为语句结束符。
所以,执行上述函数定义应该这样写:

DELIMITER $
CREATE FUNCTION avg_score(s VARCHAR(100))
RETURNS DOUBLE
BEGINRETURN (SELECT AVG(score) FROM student_score WHERE subject = s);
END $DELIMITER ;

上述通过DELIMITER将MySQL的语句结束符临时修改为$,之后再修改回来。

有时,要创建函数,可能得设置下:SET global log_bin_trust_function_creators = TRUE;

3.2.存储函数的调用
函数调用可单独使用,也可作为一个操作数与其他操作数组成复杂的表达式。
如:SELECT avg_score(‘MySQL是怎样运行的’);

3.3.查看和删除存储函数
如:SHOW FUNCTION STATUS [LIKE 需要匹配的函数名];

查看函数定义,如:SHOW CREATE FUNCTION 函数名\G
删除存储函数,如:DROP FUNCTION 函数名;

3.4.函数体的定义
3.4.1.在函数体中定义局部变量
如果我们想在存储函数的函数体中使用变量的话,必须提前使用DECLARE语句声明该变量。具体语法:
DECLARE 变量名1, 变量名2, … 数据类型 [DEFAULT 默认值];
这些在函数体内声明的变量只在该函数体内有用,当存储函数执行完成后,就不能访问这些变量了。所以,这些变量也称为局部变量。

可在一条语句中声明多个相同类型的变量。
注意的是,函数体中的局部变量不允许加@前缀(除非使用反引号将变量名引起来),这一点与之前直接使用SET语句自定义变量截然不同。在声明了这个局部变量后,在可使用它。

DELIMITER $
CREATE FUNCTION var_demo()
RETURNS INT
BEGINDECLARE c INT;SET c=5;RETURN c;
END $

如果不对声明的局部变量进行赋值,它的默认值就是NULL,当然也可通过DEFAULT子句来显式地指定局部变量的默认值,比如:

DELIMITER $
CREATE FUNCTION var_default_demo()
RETURNS INT
BEGINDECLARE c INT DEFAULT 1;RETURN c;
END $
DELIMITER ;

与用户自定义变量类似,也可把一个查询的结果赋给局部变量。

DELIMITER $
CREATE FUNCTION var_default_demo()
RETURNS DOUBLE
BEGINDECLARE c DOUBLE DEFAULT 1.0;SET c =  (SELECT AVG(score) FROM student_score WHERE subject = s);return c;
END $
DELIMITER ;

3.4.2.在函数体中使用用户自定义变量

DELIMITER $
CREATE FUNCTION user_defined_var_demo()
RETURNS INT
BEGINSET @abc = 10;RETURN @abc;
END $
DELIMITER ;

3.4.3.存储函数的参数
在定义存储函数的时候,可以指定多个参数,且每个参数都要指定对应的数据类型。
形参名不应与函数体语句中的其他变量中,列名冲突。形参不支持提供默认值。
形参,函数体内定义的参数均为局部变量。局部变量使用时候必须加@前缀。全局变量使用时必须加@前缀。
函数体内需要定义局部变量时,局部变量定义必须出现在函数体内语句的最前方。
函数体内对形参的修改不会传递到外部实参。

3.4.4.判断语句的编写
在存储函数的函数体中可使用判断语句。

IF 表达式 THEN语句列表
[ELSEIF 表达式 THEN 语句列表]
...
[ELSE 语句列表]
END IF;

如:

DELIMITER $
CREATE FUNCTION condition_demo(i INT)
RETURNS VARCHAR(10)
BEGIN
DECLARE result VARCHAR(10);
IF i = 1 THENSET result = '结果是1';
ELSEIF i = 2 THENSET result='结果是2';
ELSEIF i = 3 THENSET result='结果是3';
ELSESET result='非法参数';
END IF;
RETURN result;
END $DELIMITER ;

3.4.5.循环语句的编写
(1).WHILE循环语句
WHILE 表达式 DO
语句列表
END WHILE;

DELIMITER $
CREATE FUNCTION sum_all(n INT UNSIGNED)
RETURNS INT
BEGINDECLARE result INT DEFAULT 0;DECLARE i INT DEFAULT 1;WHILE i <= n DOSET result = result +  i;SET i = i + 1;END WHILE;RETURN result;
END $DELIMITER ;

这样执行SELECT sum_all(3);结果将是6。

(2).REPEAT语句

REPEAT语句列表
UNTIL 表达式 END REPEAT

表达式为真时,跳出循环。

CREATE FUNCTION sum_all(n INT UNSIGNED)
RETURNS INT
BEGINDECLARE result INT DEFAULT 0;DECLARE i INT DEFAULT 1;REPEATSET result = result + i;SET i = i + 1;UNTIL i > n END REPEAT;RETURN result;
END

(3).LOOP循环语句

LOOP 语句列表
END LOOP;

LOOP下要么在语句列表通过RETURN实现返回,要么通过LOOP添加标志与LEAVE的方式离开。

CREATE FUNCTION sum_all(n INT UNSIGNED)
RETURNS INT
BEGINDECLARE result INT DEFAULT 0;DECLARE i INT DEFAULT 1;LOOPIF i > n THENRETURN result;END IF;SET result = result + i;SET i = i + 1;END LOOP;
END

上述为通过RETURN实现返回

CREATE FUNCTION sum_all(n INT UNSIGNED)
RETURNS INT
BEGINDECLARE result INT DEFAULT 0;DECLARE i INT DEFAULT 1;flag:LOOPIF i > n THENLEAVE flag;END IF;SET result = result + i;SET i = i + 1;END LOOP flag;RETURN result;
END

4.存储过程
存储函数和存储过程都属于存储例程,都是对某些语句的一个封装。存储函数会给调用它的用户返回一个结果,但存储过程没返回值。

4.1.创建存储过程

CREATE PROCEDURE 存储过程名称([参数列表])
BEGIN需要执行的语句
END

存储过程不需声明返回值类型,也无法返回值。

DELIMITER $
CREATE PROCEDURE t1_operation(m1_value INT, n1_value CHAR(1))
BEGINSELECT * FROM t1;INSERT INTO t1(m1, n1) VALUES(m1_value, n1_value);SELECT * FROM t1;
END $

4.2.存储过程的调用
如果我们需调用某个存储过程,需显式使用CALL:CALL 存储过程([参数列表]);
针对上述过程这样调用:CALL t1_operation(4, 'd');

4.3.查看和删除存储过程
查看:SHOW PROCEDURE STATUS [LIKE 需要匹配的存储过程名称];
查看存储过程定义:SHOW CREATE PROCEDURE 存储过程名称;
删除存储过程:DROP PROCEDURE 存储过程名称;

4.4.存储过程中的语句
存储函数中使用的各种语句,都可用在存储过程中。

4.5.存储过程的参数前缀
比存储函数强大点的是,存储过程在定义参数的时候可选择添加一些前缀:[IN | OUT | INOUT] 参数名 数据类型
IN参考高级语言值传参,OUT参考高级语言引用传参。
(1).IN

DELIMITER $
CREATE PROCEDURE p_in(IN arg INT)
BEGINSELECT arg;SET arg = 123;
END $
DELIMITER ;

上述采用IN修饰形参

SET @a = 1;
CALL p_in(@a);
SELECT @a; // 这里a仍然为1

对IN修饰的形参,可以传递常量实参。

(2).OUT

DELIMITER $
CREATE PROCEDURE p_out(OUT arg INT)
BEGINSELECT arg;SET arg = 123;
END $
DELIMITER ;

上述采用OUT修饰形参

SET @b = 2;
CALL p_out(@b);// 这里内部执行SELECT输出值将是NULL,因为OUT修饰的形参不可用于读取值。只能被设置值。
SELECT @b; // 这里b变为123

对OUT修饰的形参,不可以传递常量实参。

(3).INOUT
INOUT修饰的变量,即可在过程内部被读取,又可被设置值且值会影响到外部实参。
如果不写明参数前缀,默认前缀是IN。

4.5.存储函数与存储过程异同
(1).存储函数定义时需通过RETURNS指定返回类型,函数体中需用RETURN指定返回值;存储过程不需要。
(2).存储函数形参不支持IN,OUT,INOUT修饰;存储过程支持。
(3).存储函数只可返回一个值;存储过程可通过OUT或INOUT返回零个或多个。
(4).存储函数不允许在函数内执行单独的select(select xxx into xxx;这样利用select作为中间结果的允许);存储过程执行过程允许支持单独的select且产生的结果集会显示在客户端。
(5).存储函数以函数调用形式调用;存储过程使用CALL形式。

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

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

相关文章

openssl+ ECC + linux 签名校验开发实例(C++)

文章目录 ECC签名过程&#xff08;ECDSA签名&#xff09;ECC验证过程&#xff08;ECDSA验证&#xff09;C示例代码 ECC&#xff08;Elliptic Curve Cryptography&#xff09;是一种基于椭圆曲线数学结构的密码学技术。在ECC中&#xff0c;签名和验证过程使用的是数字签名算法&a…

力扣.NO88 合并两个有序数组

题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并…

2 时间序列预测入门:GRU

0 论文地址 GRU 原论文&#xff1a;https://arxiv.org/pdf/1406.1078v3.pdf GRU&#xff08;Gate Recurrent Unit&#xff09;是循环神经网络&#xff08;RNN&#xff09;的一种&#xff0c;可以解决RNN中不能长期记忆和反向传播中的梯度等问题&#xff0c;与LSTM的作用类似&a…

C语言第三十弹---打印一个整数的每一位数

C语言实现打印整数的每一位数 逆序打印整数 思路&#xff1a;通过n%10可以获得整数的个位&#xff0c;获得个位后&#xff0c;整数/10就看去掉个位&#xff0c;得到新的一个数。循环即可获得所有数。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>void print(i…

设计模式-开篇

什么是设计模式 设计模式是一种被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。设计模式不是可直接转化为代码的完成解决方案&#xff0c;而是描述了如何解决一个问题的经过&#xf…

图论——二部图及其算法

什么是二部图 二部图的判定 例子1 任选一个节点染成红色 红色的邻居染成蓝色 蓝色邻居染成红色 例子2 这个不是二部图 无权二部图的最大匹配

Jacobi迭代与SOR迭代求解希尔伯特矩阵

给出线性方程组 Hn*x b&#xff0c;其中系数矩阵Hn为希尔伯特矩阵&#xff1a; 假设 x ∗ (1, 1, . . . , 1)T&#xff0c;b Hnx ∗。若取 n 6,8, 10&#xff0c;分别用 Jacobi 迭代法及 SOR迭代&#xff08;ω 1, 1:25,1:5&#xff09;求解&#xff0c;比较计算结果。…

leetcode做题笔记1457. 二叉树中的伪回文路径

给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值的排列中&#xff0c;存在一个回文序列。 请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。 示例 1&#xff1a; 输…

【计算机网络笔记】多路访问控制(MAC)协议——随机访问MAC协议

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Error PostCSS plugin autoprefixer requires PostCSS 8

文章目录 一、情况一二、情况二三、总结 在启动 vue项目时&#xff0c;突然控制台报错&#xff1a; Error: PostCSS plugin autoprefixer requires PostCSS 8。然后依次出现下面几种情况&#xff0c;依次解决完&#xff0c;项目就可以正常启动了 一、情况一 error in ./src/…

万宾科技可燃气体监测仪的功能有哪些?

随着城市人口的持续增长和智慧城市不断发展&#xff0c;燃气作为一种重要的能源供应方式&#xff0c;已经广泛地应用于居民生活和工业生产的各个领域。然而燃气泄漏和安全事故的风险也随之增加&#xff0c;对城市的安全和社会的稳定构成了潜在的威胁。我国燃气管道安全事故的频…

redhat9.3配置国内yum阿里源

由于新建的Redhat9.3在未注册激活之前是没有yum源的配置文件的&#xff0c;所以需要我们自己新建一个yum源文件的配置文件 vim /etc/yum.repos.d/aliyun_yum.repo 内容如下&#xff1a; [ali_baseos] nameali_baseos baseurlhttps://mirrors.aliyun.com/centos-stream/9-str…

基于Flutter的图片浏览器的实现

一 效果展示&#xff1a; 1. 图片展示&#xff1a; 2.混色&#xff0c;平铺&#xff0c;拉伸&#xff0c;原图展示 二 实验准备&#xff1a; 1.在包结构中创建images包来存放我们用到的图片&#xff0c;在pubspec.yaml中声明路径&#xff1a; 2. 检查虚拟机是否正常运行&…

面试问题--内存泄漏和内存溢出

解决内存溢出和内存泄漏的方法 内存溢出&#xff08;Memory Overflow&#xff09;和内存泄漏&#xff08;Memory Leak&#xff09;是常见的内存管理问题&#xff0c;可能导致程序崩溃或系统性能下降。下面是一些排除这两个问题的方法&#xff1a; 1. 区别&#xff1a;内存溢出…

crontab计划任务

银河麒麟v10服务器版和桌面版执行周期计划任务分为两类&#xff1a;系统任务调度和用户任务调度。系统任务是由 cron (crond) 这个系统服务来控制的&#xff0c;这个系统服务是默认启动的&#xff0c;通过vim /etc/crontab执行。用户自己设置的计划任务则使用crontab 命令 配置…

Vue 3

Vu3 简述: 快速上手,开发即用,具体知识参考官方文档 具备知识 Vite 了解即可,使用时按需配置,更多参考官方文档( https://cn.vitejs.dev) 简述: 极速响应工具 (构建、启动、更新、插件使用等) 核心思想: 依赖 和 源码 工作原理: 引入rollup: 灵活,相比webpack速度快,…

数据结构——堆的实现(详解)

呀哈喽&#xff0c;我是结衣。 堆的介绍 如果有一个关键码的集合K {k0,k1,k2,…,kn-1},把它的所有元素按照完全二叉树的顺序储存方式储存在一个一维数组中&#xff0c;并满足&#xff1a;Ki<K2i1且ki<K2i2(Ki>K2i1且Ki>-K2i2)i 1,2,3…,则称为小堆&#xff08;或…

Windows系统管理之备份与恢复

本章目录&#xff1a; 一. 本章须知&#xff1a; 前置条件 需要创建一个新的磁盘 前置条件2 给新添加的磁盘分盘 二. 了解开启并学会使用Windows sever backup 如何使用备份与恢复“备份计划”“一次性备份”“恢复” 最后是用命令行“一次性备份命令 ”完成一次备份 话不多说 …

React中如何解决点击<Tree>节点前面三角区域不触发onClick事件

React中如何解决点击节点前面三角区域不触发onClick事件&#xff0c;如何区别‘左边’和‘右边’区域点击逻辑呢&#xff1f;&#xff08;Tree引用开源组件TDesign&#xff09; 只需要在onClick里面加限制一下就行&#xff1a; <TreeexpandMutexactivabletransitiondata{t…

从0开始学习JavaScript--JavaScript函数返回值

在JavaScript中&#xff0c;函数是一种强大的工具&#xff0c;不仅能够执行一系列操作&#xff0c;还可以返回值。理解函数返回值的概念对于编写清晰、灵活的代码至关重要。本文将深入探讨JavaScript函数返回值的各种方面&#xff0c;包括基本返回值、多返回值、异步函数的返回…