mysql存储过程

一、存储过程简介

存储过程跟触发器有点类似,都是一组SQL集,但是存储过程是主动调用的,且功能比触发器更加强大,触发器是某件事触发后自动调用;
我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中(执行创建存储过程的语句,即完成编译和存储),用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象**方法**的模拟(类似于JAVA语言中的方法)。它允许控制数据的访问方式。

存储过程通常有以下优点:

(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。

(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

二、创建存储过程

2.1 语法
DELIMITER 分隔符
CREATE PROCEDURE 过程名 ([ [IN |OUT |INOUT ] 参数名 数据类形… ]) [特性 …] 过程体
DELIMITER ;//恢复mysql默认的分隔符;
存储过程可以有形参,也可无形参;
可以有返回值,也可以没有返回值;如果有返回值,则在形参中指定

IN 输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回
OUT 输出参数:该值可在存储过程内部被改变,并可返回
INOUT 输入输出参数:调用时指定,并且可被改变和返回
in、 out、 inout不填写,默认为in,即默认为输入参数
可以包含多个输出参数
过程体: 过程体的开始与结束使用BEGIN与END进行标识。

存储过程是和某个数据库关联的,所有上面的创建语句使用的前提
use databasename;//切换到指定数据库

或者,在创建时使用数据库名. 前缀的方式

特性,有以下取值:
LANGUAGE SQL:说明下面过程体body部分是由SQL语句组成,是系统默认的,为今后mysql会支持的除sql外的其他语言支持的存储过程准备的。

[NOT] DETERMINISTIC:指明存储过程执行的结果是否正确。

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

{ CONTAINS SQL | NO SQL |REDAS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL语句的限制。

1. CONTAINS SQL:表示子程序包含SQL语句,但是不包含读写数据的语句。

2. NO SQL:表示子程序不包含SQL语句。

3. REDAS SQL DATA :说明子程序包含数据的语句。

4. MODIFIES SQL DATA:表明子程序包含写数据的语句。默认为CONTAINS SQL。

SQL SECURITY { DEFINER | INVOKER}:指明谁有权限来执行。

1. DEFINER表示只有定义者才能执行。

2. INVOKER表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER

COMMENT ‘string’:注释信息,可以用来描述存储过程或函数。

三、 变量的使用

在存储过程、函数、触发器等中,可以定义和使用变量。用户可以使用DECLARE关键字来定义变量。然后可以为变量赋值。这些变量的作用范围是BEGIN…END程序段中,即局部变量。本小节将讲解如何定义变量和为变量赋值。

1.定义变量

MySQL中可以使用DECLARE关键字来定义变量。定义变量的基本语法如下:

DECLARE var_name1 [,var_name2…] type [DEFAULT value]
其中, DECLARE关键字是用来声明变量的;var_name参数是变量的名称,这里可以同时定义多个变量;type参数用来指定变量的类型;DEFAULT value子句将变量默认值设置为value,没有使用DEFAULT子句时,默认值为NULL。

【示例】 下面定义变量my_sql,数据类型为INT型,默认值为10。代码如下:

DECLARE my_sql INT DEFAULT 10 ;
2.为变量赋值

MySQL中可以使用SET关键字来为变量赋值。SET语句的基本语法如下:

SET var_name1 = expr1 [, var_name2 = expr2 … ]
其中,SET关键字是用来为变量赋值的;var_name参数是变量的名称;expr参数是赋值表达式。一个SET语句可以同时为多个变量赋值,各个变量的赋值语句之间用逗号隔开。

【示例】 下面为变量my_sql赋值为30。代码如下:

SET my_sql = 30 ;
MySQL中还可以使用SELECT…INTO语句为变量赋值。其基本语法如下:

SELECT col_name[,…] INTO var_name[,…]
FROM table_name WEHRE condition
其中,col_name参数表示查询的字段名称;var_name参数是变量的名称;table_name参数指表的名称;condition参数指查询条件。

【示例】 下面从employee表中查询id为2的记录,将该记录的d_id值赋给变量my_sql。代码如下:

SELECT d_id INTO my_sql
FROM employee WEHRE id=2 ;

四、用户变量

1 用户变量介绍
用户变量即用户自己定义的变量,我们可以给用户变量分配值,并且可用在任何可以正常使用标量表达式的地方。
引入用户变量之前我们必须使用set语句或select语句来定义它,然后为它赋一个值,否则变量就只有一个空值。
用户变量与连接有关。也就是说,一个客户端定义的变量不能被其它客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。-----即全局变量
2 用户变量定义
set语句可用于向系统变量或用户变量赋值,针对用户变量的定义如下:
SET @var_name = expr [, @var_name = expr] …
也可使用select语句来定义:
SELECT @var_name := expr [, @var_name = expr] …
· 用户变量:以"@“开始·,形式为”@var_name",以区分用户变量及列名。它可以是任何随机的,复合的标量表达式,只要其中没有列指定。
一个变量名可以由当前字符集的数字字母字符和“_”、“$”和“.”组成。缺省字符集是ISO-8859-1 Latin1;这可以用mysqld 的–default-character-set 选项更改字符集。
对于SET,可以使用=或:=来赋值,对于SELECT只能使用:=来赋值。
我们可以使用一条简单的select语句查询定义的用户变量的值。
3 用户变量的使用
3.1 通过set的实例
用来把一个值赋给一个变量的标量表达式可以是复合表达式。计算,函数,系统标量以及其他用户变量都是允许的,子查询也是允许的。然后通过select语句可以获取一个用户变量的值,结果是带有一行的一个表。

mysql> set @var1=1, @var2=‘vartest’, @var3=abs(-2), @var4=(select count(*) from mysql.user);
mysql> select @var1, @var2, @var3, @var4;
±------±--------±------±------+
| @var1 | @var2 | @var3 | @var4 |
±------±--------±------±------+
| 1 | vartest | 2 | 25 |
±------±--------±------±------+
在用来为一个用户变量赋值的表达式中,也可以指定其它的用户变量,需要注意的是mysql首先确定所有表达式的值,之后才会把值赋给变量。
例如:
mysql> set @varA = 2;
对于下面两个例子,varB的值是不同的。
例1:
mysql> set @varA = 3, @varB = @varA;
mysql> select @varB;
±------+
| @varB |
±------+
| 2 |
±------+
例2:
mysql> set @varA = 3;
mysql> set @varB = @varA;
mysql> select @varB;
±------+
| @varB |
±------+
| 3 |
注意:滥用用户变量会导致程序难以理解及管理

五、调用存储过程

#调用存储过程
CALL 存储过程名(参数1…参数n);

六、示例

创建表
create table user{
id BIGINT primary key auto_increment,
name varchar(20) ,
salary float
}o
insert into user(name,salary) values(“张三”,5000),(“李四”,5500);

(1)给员工加薪:加薪的金额(salary),员工编号(id)
java代码:
public BOOLEAN addSalary(FLOAT money,INT id){
代码块;
RETURN TRUE;
}

#存储过程:是一组sql语句的集合
DELIMITER //
CREATE PROCEDURE addSalary(money FLOAT,idd BIGINT)
BEGIN
UPDATE user SET salary=salary+money WHERE id=idd;
END//
DELIMITER ;

#调用存储过程:call 存储过程名()
CALL addSalary(1000,1);

(2)带返回值的存储过程
#test1:传递两个float类型的形参,返回两个数的和
java代码
public FLOAT test1(FLOAT i,FLOAT j){
FLOAT num = i+j;
RETURN num;
}

DELIMITER //
CREATE PROCEDURE test1(IN i FLOAT,IN j FLOAT,OUT num FLOAT)
BEGIN
SET num=i+j;
END//
DELIMITER ;

CALL test1(10,20,@result) //将存储过程的输出存入@result
SELECT @result

#书写一个存储过程,将users表中的所有money之和返回
SELECT SUM(money) FROM users;
DELIMITER //
CREATE PROCEDURE pro_qiuSum(OUT total FLOAT)
BEGIN
SELECT SUM(money) INTO total FROM users;
END//
DELIMITER ;

CALL pro_qiuSum(@a);
SELECT @a;

七、带流程控制的示例

(1)带if语句的存储过程
#加薪的存储过程,传递两个参数:id、m(只能够传递正数,不能够传递负数)
SELECT ‘亲,您输入的金额不能够为负数!!!’ AS ‘友情提示’;

DELIMITER //
CREATE PROCEDURE pro_addSalary(idd BIGINT,m FLOAT)
BEGIN
IF m>0 THEN
UPDATE users SET money=money+m WHERE id=idd;
END IF;
END//
DELIMITER ;

CALL pro_addSalary(1,-500);

(2)带if..else的存储过程
DROP PROCEDURE IF EXISTS pro_salaryAdd;
DELIMITER //
CREATE PROCEDURE pro_salaryAdd(idd BIGINT,m FLOAT)
BEGIN
IF m>0 THEN
UPDATE users SET money=money+m WHERE id=idd;
ELSE
SELECT ‘亲,您输入的金额不能够为负数!!!’ AS ‘友情提示’;
END IF;
END//
DELIMITER ;

CALL pro_salaryAdd(1,-2000);

(3)带if...else if...else语句的存储过程
#存储过程名:pro_buyCar(money float),如果money>500万则买保时捷;否则如果money>300万,买宝马;否则如果money>10万买奥拓;否则骑摩拜
DELIMITER //
CREATE PROCEDURE pro_buyCar(money FLOAT)
BEGIN
IF money>500 THEN
SELECT ‘买保时捷’ AS ‘买啥’;
ELSEIF money>300 THEN
SELECT ‘宝马’ AS ‘买啥’;
ELSEIF money>10 THEN
SELECT ‘奥拓’ AS ‘买啥’;
ELSE
SELECT ‘骑摩拜’ AS ‘骑啥’;
END IF;
END//
DELIMITER ;

CALL pro_buyCar(5);

(4)case选择分支结构
#存储过程名:pro_case(i int),如果i=1则打印星期一,i=2则打印星期二…
DELIMITER //
CREATE PROCEDURE pro_case(i INT)
BEGIN
CASE i
WHEN 1 THEN
SELECT ‘星期一’ AS ‘日期’;
WHEN 2 THEN
SELECT ‘星期二’ AS ‘日期’;
ELSE
SELECT ‘今天不是周一或者周二,到底周几你猜?’ AS ‘日期’;
END CASE;
END//
DELIMITER ;

CALL pro_case(3);

(5)while循环
#Java中while循环的语法:
WHILE(条件){
循环体;
循环终止条件;
}
#存储过程名:pro_while2(i int),如果i=100,则计算1到100之间的所有数之和,返回最终结果
DELIMITER //
CREATE PROCEDURE pro_while2(IN i INT,OUT total INT)
BEGIN
DECLARE a INT DEFAULT 1;
SET total=0;
WHILE a<=i DO
SET total=total+a;
SET a=a+1;
END WHILE;
END//
DELIMITER ;

CALL pro_while2(100,@aaa);
SELECT @aaa;

#往users表中插入i条数据
DROP PROCEDURE IF EXISTS pro_while1;
DELIMITER //
CREATE PROCEDURE pro_while1(IN i INT)
BEGIN
DECLARE a INT DEFAULT 1;
WHILE a<=i DO
INSERT INTO users SET username=‘test’,money=100;
SET a=a+1;
END WHILE;
END//
DELIMITER ;

CALL pro_while1(10);
SELECT COUNT(*) FROM users;
TRUNCATE TABLE users;//删除表中的数据,且自增自动重新从0开始计算,delete方式,自增不会重新从0开始计算

#------------------------找出1-100之间能够被3整除的所有数之和-----------------------------
DROP PROCEDURE IF EXISTS pro_sum;
DELIMITER //
CREATE PROCEDURE pro_sum()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE total INT DEFAULT 0;
WHILE i<=10 DO
IF i MOD 3=0 THEN
SET total=total+i;
END IF;
SET i = i+1;#循环结束条件
END WHILE;
SELECT total;
END//
DELIMITER ;

CALL pro_sum();

(6)loop循环:
CREATE PROCEDURE 存储过程名()
BEGIN
loop循环别名:LOOP
循环体;

	LEAVE loop循环别名;
END LOOP;

END;

#通过loop循环往users表中同时添加100条记录
DELIMITER //
CREATE PROCEDURE pro_loop()
BEGIN
DECLARE i INT DEFAULT 0;
loop_test1:LOOP
INSERT INTO users SET username=‘admin’,money=200;

	SET i = i+1;
	IF i=100 THEN
		LEAVE loop_test1;//退出循环
	END IF;
END LOOP;

END//
DELIMITER ;

CALL pro_loop();

(7)ITERATE、repeat
不再详细介绍

九、删除存储过程

drop procedure [if exists] 存储过程名;

存储过程是和某个数据库关联的,所有上面的创建语句使用的前提
use databasename;//切换到指定数据库

或者,在创建时使用数据库名. 前缀的方式

十、光标

在存储过程和函数中可以使用光标对结果集进行循环的处理。
注意:
declare可以声明变量、条件、处理程序、光标,它们之前是有先后顺序的,变量和条件必须在最前面声明,然后才是光标,最后是处理程序。

声明光标

DECLARE cursor_name CURSOR FOR select_statement
这个语句声明一个光标。也可以在子程序中定义多个光标,但是一个块中的每一个光标必须有唯一的名字。
其中,cursor_name参数表示光标的名称;select_statement参数表示SELECT语句的内容

SELECT语句不能有INTO子句。

open光标

OPEN cursor_name

这个语句打开先前声明的光标。

fetch光标

FETCH cursor_name INTO var_name [, var_name] …

用指定的打开光标读取下一行(如果有下一行的话),并且前进光标指针。

close光标
CLOSE cursor_name

这个语句关闭先前打开的光标。

如果未被明确地关闭,光标在它被声明的复合语句的末尾被关闭。
示例:
DELIMITER //
CREATE PROCEDURE guangbiao()
BEGIN
DECLARE a VARCHAR(20);
DECLARE b int DEFAULT 0;
DECLARE myguangbiao CURSOR for SELECT title from 测试.articless;
OPEN myguangbiao;

read_loop:LOOP
FETCH myguangbiao into a;
IF b=1 THEN
LEAVE read_loop;//结束循环
end IF;
INSERT into 测试.aaa(text1) VALUE(a);
set b=1;
END LOOP read_loop;
CLOSE myguangbiao;
END //
DELIMITER ;

call guangbiao();

十一、 定义条件和处理程序

定义条件和处理程序是事先定义程序执行过程中可能遇到的问题。并且可以在处理程序中定义解决这些问题的办法。这种方式可以提前预测可能出现的问题,并提出解决办法。这样可以增强程序处理问题的能力,避免程序异常停止。MySQL中都是通过DECLARE关键字来定义条件和处理程序。本小节中将详细讲解如何定义条件和处理程序。
1.定义条件

MySQL中可以使用DECLARE关键字来定义条件。其基本语法如下:

DECLARE condition_name CONDITION FOR condition_value
condition_value:
SQLSTATE [VALUE] sqlstate_value | mysql_error_code
其中,condition_name参数表示条件的名称;condition_value参数表示条件的类型;sqlstate_value参数和mysql_error_code参数都可以表示MySQL的错误。例如ERROR 1146 (42S02)中,sqlstate_value值是42S02,mysql_error_code值是1146。

【示例】 下面定义"ERROR 1146 (42S02)"这个错误,名称为can_not_find。可以用两种不同的方法来定义,代码如下:

//方法一:使用sqlstate_value
DECLARE can_not_find CONDITION FOR SQLSTATE ‘42S02’ ;
//方法二:使用mysql_error_code
DECLARE can_not_find CONDITION FOR 1146 ;
2.定义处理程序

MySQL中可以使用DECLARE关键字来定义处理程序。其基本语法如下:

DECLARE handler_type HANDLER FOR condition_value[,…] sp_statement
handler_type:
CONTINUE | EXIT | UNDO
condition_value:
SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING
| NOT FOUND | SQLEXCEPTION | mysql_error_code
其中,handler_type参数指明错误的处理方式,该参数有3个取值。这3个取值分别是CONTINUE、EXIT和UNDO。CONTINUE表示遇到错误不进行处理,继续向下执行;EXIT表示遇到错误后马上退出;UNDO表示遇到错误后撤回之前的操作,MySQL中暂时还不支持这种处理方式。

注意:通常情况下,执行过程中遇到错误应该立刻停止执行下面的语句,并且撤回前面的操作。但是,MySQL中现在还不能支持UNDO操作。因此,遇到错误时最好执行EXIT操作。如果事先能够预测错误类型,并且进行相应的处理,那么可以执行CONTINUE操作。

condition_value参数指明错误类型,该参数有6个取值。sqlstate_value和mysql_error_code与条件定义中的是同一个意思。condition_name是DECLARE定义的条件名称。SQLWARNING表示所有以01开头的sqlstate_value值。NOT FOUND表示所有以02开头的sqlstate_value值。SQLEXCEPTION表示所有没有被SQLWARNING或NOT FOUND捕获的sqlstate_value值。sp_statement表示一些存储过程或函数的执行语句。

【示例】 下面是定义处理程序的几种方式。代码如下:

//方法一:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘42S02’ SET @info=‘CAN NOT FIND’;
//方法二:捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info=‘CAN NOT FIND’;
//方法三:先定义条件,然后调用
DECLARE can_not_find CONDITION FOR 1146 ;
DECLARE CONTINUE HANDLER FOR can_not_find SET @info=‘CAN NOT FIND’;
//方法四:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info=‘ERROR’;
//方法五:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info=‘CAN NOT FIND’;
//方法六:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info=‘ERROR’;
上述代码是6种定义处理程序的方法。第一种方法是捕获sqlstate_value值。如果遇到sqlstate_value值为42S02,执行CONTINUE操作,并且输出"CAN NOT FIND"信息。第二种方法是捕获mysql_error_code值。如果遇到mysql_error_code值为1146,执行CONTINUE操作,并且输出"CAN NOT FIND"信息。第三种方法是先定义条件,然后再调用条件。这里先定义can_not_find条件,遇到1146错误就执行CONTINUE操作。第四种方法是使用SQLWARNING。SQLWARNING捕获所有以01开头的sqlstate_value值,然后执行EXIT操作,并且输出"ERROR"信息。第五种方法是使用NOT FOUND。NOT FOUND捕获所有以02开头的sqlstate_value值,然后执行EXIT操作,并且输出"CAN NOT FIND"信息。第六种方法是使用SQLEXCEPTION。SQLEXCEPTION捕获所有没有被SQLWARNING或NOT FOUND捕获的sqlstate_value值,然后执行EXIT操作,并且输出"ERROR"信息。

3. 示例
数据库companys:
在这里插入图片描述
查看数据库中的表:
在这里插入图片描述

查看userinfo的字段,这里面有3个字段。
在这里插入图片描述
查看表中数据,有4个数据。
在这里插入图片描述
查看employees表中字段。
在这里插入图片描述
创建存储过程,向employees表和userinfo这两张表中插入数据
delimiter $$
create procedure p_insertDemo1()

begin
insert into userinfo<userid,username,userpwd> values(1,‘ui’,‘123’);
insert into employees<emp_no,birth_date,first_name,last_name,gender,hire_date> values(5098,‘1990-1-1’,‘ui’,‘jm’,‘M’,‘2014-12-1’);
end $$

delimiter ;

调用存储过程,调用的时候已经出错了,这个出错会影响到我们后面代码的执行
call p_insertDemo1();
在这里插入图片描述
出错位置:
在这里插入图片描述
它出错以后,mysql它不会执行下面这段代码。
在这里插入图片描述
如果我们想上面的代码出错了,下面的代码一样能够进行,我们就要用到定义条件和处理程序。它的理解是:当我们有程序代码出错的时候,它就会告诉你这个程序代码,会捕获到这个错误,然后会继续执行下面的代码。查询刚刚插入的内容,没有找到5098的内容。

我们修改一下原来的代码,按照格式。declare continue handler for sqlstate ‘错误代码值’ set 变量=变量值
delimiter $$
create procedure p_insertDemo2()

begin
declare continue handler for sqlstate ‘23000’ set @x=1;
insert into userinfo<userid,username,userpwd> values(1,‘ui’,‘123’);
insert into employees<emp_no,birth_date,first_name,last_name,gender,hire_date> values(5098,‘1990-1-1’,‘ui’,‘jm’,‘M’,‘2014-12-1’);
end $$

delimiter ;

执行存储过程:
call p_insertDemo2();

查询一下,5098已经插入成功。
在这里插入图片描述
但是这条数据并没有创建成功,因为这条数据已经是组建了的。
在这里插入图片描述

创建存储过程,向不存在的表中插入数据6098:
delimiter $$
create procedure p_insertDemo3()

begin
declare continue handler for sqlstate ‘23000’ set @x=1;
insert into userinfo2<userid,username,userpwd> values(1,‘ui’,‘123’);
insert into employees<emp_no,birth_date,first_name,last_name,gender,hire_date> values(6098,‘1990-1-1’,‘ui’,‘jm’,‘M’,‘2014-12-1’);
end $$

delimiter ;

调用存储过程,这里面已经报错,这张表不存在。
call p_insertDemo3();
在这里插入图片描述
6098没有插入进去。
在这里插入图片描述

重新创建存储过程,修改为42s02的错误。
delimiter $$
create procedure p_insertDemo4()

begin
declare continue handler for sqlstate ‘42S02’ set @x=1;
insert into userinfo2<userid,username,userpwd> values(1,‘ui’,‘123’);
insert into employees<emp_no,birth_date,first_name,last_name,gender,hire_date> values(6098,‘1990-1-1’,‘ui’,‘jm’,‘M’,‘2014-12-1’);
end $$

delimiter ;

调用这个存储过程,一条已经影响,因为我们已经处理了42s02的错误,我们捕获了42s02的错误,捕获之后,即使这条代码遇到错误,后面的也会继续执行。
修改分隔符。
查询一下,6098已经插入
在这里插入图片描述

十二、存储过程和存储函数的区别

一、 存储函数有且只有一个返回值,而存储过程不能有返回值。
二、 函数只能有输入参数,而且不能带in, 而存储过程可以有多个in,out,inout参数。
三、 存储过程中的语句功能更强大,存储过程可以实现很复杂的业务逻辑,而函数有很多限制,如不能在函数中使用insert,update,delete,create等语句;存储函数只完成查询的工作,可接受输入参数并返回一个结果,也就是函数实现的功能针对性比较强。
四、 存储过程可以调用存储函数。但函数不能调用存储过程。
五、 存储过程一般是作为一个独立的部分来执行(call调用)。而函数可以作为查询语句的一个部分来调用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值