存儲過程和存儲函數


存儲過程和存儲函數
定義:
存儲過程和存儲函數是事先經過編譯並存儲在數據庫中的一段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