存储过程和存储函数


存储过程和存储函数
定义:
存储过程和存储函数是事先经过编译并存储在数据库中的一段sql语句的集合。存储过程在高并发数据中使用的比较多。
区别:
1.存储函数必须有返回值,而存储过程没有返回值。
2.存储过程的参数可以是in ,out ,inout类型,存储函数的参数类型只能是in
优点:
1.存储过程只在创建时进行编译,sql语句则每次执行都需要编译。能提高数据库执行速度。
2.简单复杂操作结合事物一起封装。
3.复用性高。
4.安全性高,可指定存储过程的使用权。
创建存储过程:
delimiter是定界符
delimiter声明当前分隔符:
MySQL默认以";"为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL
语句进行处理,因此编译过程会报错,所以要事先用“DELIMITER //”声明当前段分隔符,
让编译器把两个"//"之间的内容当做存储过程的代码,不会执行这些代码;“DELIMITER ;
”的意为把分隔符还原。
例1:
DELIMITER //
CREATE PROCEDURE myproc(OUT s int)
BEGIN
SELECT COUNT(*) INTO s FROM students;
END
//
 
DELIMITER;
 
调用proc过程
call proc(@a);
 
查询@a
select @a as 新字段名;
例2:
delimiter //
create procedure proc2()
begin declare xf_id char(10); declare在sql语句中是声明变量
declare xs_id int(10);
set xf_id='a3'; set在sql语句中是给变量赋值
set xs_id=107;
insert into fruits(f_id,s_id)values(xf_id,xs_id);
end //
 
delimiter ; 这个delimiter和分号之间要有一个空格
调用存储过程:
call proc2();
例3:
DELIMITER //
CREATE PROCEDURE CountProc1 (IN sid INT, OUT num INT)
BEGIN
SELECT COUNT(*) INTO num FROM fruits WHERE s_id = sid;
END //
DELIMITER ;
CALL CountProc1 (101, @num);
select @num;
 
创建存储函数:
例1:
DELIMITER //
create function fun1(in s char(20) ) returns char(50)
return concat('hello',s,'!!');
//
 
DELIMITER;
查询
select fun1('刘德华') as '粉丝的呼唤';
例2:
DELIMITER //
CREATE FUNCTION NameByZip()
RETURNS CHAR(50)
RETURN (SELECT s_name FROM suppliers WHERE s_call= '48075');
//
把DELIMITER换回“;”
DELIMITER;
调用NameByZip()的返回值
select NameByZip();
例3:
查询存储过程和函数信息:
show create procedure 存储过程名;
SHOW CREATE FUNCTION test.CountProc \G
SHOW PROCEDURE STATUS LIKE 'C%' \G
 
SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME='CountProc' AND ROUTINE_TYPE = 'FUNCTION' \G
 
SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,SECURITY_TYPE
FROM information_schema.Routines
WHERE ROUTINE_NAME='CountProc' AND ROUTINE_TYPE='PROCEDURE';
 
show create function 存储函数名;
 
MySQL存储过程的修改:
ALTER PROCEDURE 更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。
 
ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic:
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
sp_name参数表示存储过程或函数的名称;
characteristic参数指定存储函数的特性。
CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
NO SQL表示子程序中不包含SQL语句;
READS SQL DATA表示子程序中包含读数据的语句;
MODIFIES SQL DATA表示子程序中包含写数据的语句。
SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
COMMENT 'string'是注释信息。
删除存储过程和函数:
drop procedure if exists 存储过程名;
drop function if exists 存储过程名;
存储过程的综合应用:
创建sch表:
CREATE TABLE sch(id INT, name VARCHAR(50),glass VARCHAR(50));
INSERT INTO sch VALUE(1,'xiaoming','glass 1'), (2,'xiaojun','glass 2');
存储函数:
DELIMITER //
CREATE FUNCTION count_sch()
RETURNS INT
RETURN (SELECT COUNT(*) FROM sch);
//
存储过程:
DELIMITER //
CREATE PROCEDURE add_id(out count INT)
BEGIN
DECLARE itmp INT;
--光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明。
DECLARE cur_id CURSOR FOR SELECT id FROM sch; --声明光标
--这个语句声明一个光标。也可以在子程序中定义多个光标,但是一个块中的每一个光标必须有唯一的名字。
--SELECT语句不能有INTO子句。
DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_id; --定义条件程序处理
--NOT FOUND捕获所有以02开头的sqlstate_value值,然后执行EXIT操作,并且关闭光标
SELECT count_sch() INTO count;
SET @sum=0;
OPEN cur_id; --打开光标
REPEAT --repeat循环
FETCH cur_id INTO itmp; --从光标中抓取数据
IF itmp<10
THEN SET @sum= @sum+itmp;
END IF;
UNTIL 0 END REPEAT;
CLOSE cur_id; --关闭光标
如果未被明确地关闭,光标在它被声明的复合语句的末尾被关闭。
END //
 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM