欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL存儲過程的創(chuàng)建和使用示例詳解

 更新時間:2025年02月07日 09:53:57   作者:m0_74825488  
文章介紹了MySQL存儲過程的概念、創(chuàng)建與刪除、調用、變量使用、參數、流程控制、管理和案例,存儲過程可以封裝SQL指令,提高執(zhí)行效率,但也有一定局限性,感興趣的朋友跟隨小編一起看看吧

一、存儲過程

1.1 存儲過程介紹

存儲過程:

將能夠完成特定功能的SQL指令進行封裝(SQL指令集),編譯之后存儲在數據庫服務器上,并為其命名,客戶端可以通過直接調用SQL指令集,獲取執(zhí)行結果

存儲過程解決的問題:

  • 如果有需要多次執(zhí)行的SQL,每次執(zhí)行都需要通過連接傳遞到MySQL服務器,并且需要經過編譯和執(zhí)行后,再返回執(zhí)行結果。重復且浪費資源
  • 如果需要連續(xù)執(zhí)行多個SQL指令,并且第二個SQL指令需要使用第一個SQL執(zhí)行的結果集作為參數。

存儲過程優(yōu)點:

  • SQL指令無需客戶端編寫、通過網絡傳輸,可以節(jié)省網絡開銷,同時避免SQL指令在傳輸過程中被惡意篡改,保證安全性;
  • 存儲過程經過編譯創(chuàng)建并保存在數據庫服務器中,執(zhí)行過程無需編譯,對SQL指令的執(zhí)行過程提升了性能;
  • 存儲過程中多個SQL指令之間存在邏輯關系,支持流程控制語句(分支、循環(huán)),可以實現更為復雜的業(yè)務邏輯處理;

存儲過程的缺點:

  • 存儲過程是根據不同數據庫引擎進行編譯、創(chuàng)建并存儲在數據庫中。如果需要不同類型數據庫遷移,需要對數據庫存儲過程進行重新編寫。
  • 存儲過程受限與數據庫產品,如果需要高性能的優(yōu)化會成為一個問題;
  • 在互聯網項目中,如果需要數據庫高并發(fā)(連接)訪問,存儲過程會增加數據庫的連接執(zhí)行時間。因為我們將復雜的業(yè)務交給了數據庫進行處理。

1.2 存儲過程的創(chuàng)建與刪除

1.2.1 創(chuàng)建存儲過程

將能夠完成特定功能的SQL指令進行封裝

語法

CREATE PROCEDURE <proc_name>([IN/OUT args])
BEGIN
	-- SQL
END;

示例

-- 創(chuàng)建存儲過程,實現加法運算
-- 存儲過程是有出入參數和輸出參數的
CREATE PROCEDURE proc_test1(IN a INT,IN b INT,OUT c INT)
BEGIN
	SET c = a+b;
END;

1.2.2 刪除存儲過程

-- 刪除存儲過程
DROP PROCEDURE proc_test1;

1.3存儲過程的調用

-- 定義變量
SET @m = 0;
-- 調用存儲過程
CALL proc_test1(3,2,@m);
-- 顯示變量值
SELECT @m from DUAL;

1.4 存儲過程中的變量使用

存儲過程中的變量分為兩種:局部變量和用戶變量

1.4.1 局部變量

局部變量:定義在存儲過程中的變量,只能在存儲過程內部使用

-- 局部變量需要定義在存儲過程中,而且必須定義在存儲過程開始
declare <attr_name> <type> [default value];
-- 創(chuàng)建存儲過程:計算輸入參數的平方與輸入參數/2 之和
CREATE PROCEDURE proc_test2(IN a INT,OUT r INT)
BEGIN
	DECLARE x INT DEFAULT 0; -- 局部變量定義
	DECLARE y INT DEFAULT 0; -- 局部變量定義
	set x = a*a;
	set y = a/2;
	SET r = x + y ;
END

1.4.2 用戶變量

用戶變量:相當于全局變量,定義的用戶變量,可以通過 select @attrName from dual進行查詢;

-- 用戶變量會存儲在mysql數據庫的數據字典中(dual)
-- 用戶變量定義使用set關鍵字直接定義,變量名要以@開頭
SET @a = 0; -- 定義用戶變量
SELECT @a from DUAL;-- 查詢用戶變量

1.4.3 將查詢結果賦值給變量

在存儲過程中,使用 select ... into 給變量賦值

-- 創(chuàng)建存儲過程,查詢學生表中的學生數量,賦值給參數s
CREATE PROCEDURE proc_test3(OUT s INT)
BEGIN
	SELECT COUNT(stu_num) INTO s from students;-- 將查詢到的學生數量,賦值給參數s
END;
-- 調用存儲過程test3
SET @s=0;
CALL proc_test3(@s);
select @s from DUAL;

注意

用戶變量相當于全局變量,可以在SQL質量以及多個存儲過程中共享,因此在開發(fā)中建議盡量減少使用用戶變量,防止用戶變量過多導致程序不易理解、難以維護;

1.5存儲過程的參數

MySQL存儲過程的參數一共有三種:IN 、OUT、INOUT

1.5.1 輸入參數 IN

輸入參數–在調用存儲過程中傳遞給存儲過程的參數(在調用的過程必須為具有實際變量的 或者 字面值)

-- 創(chuàng)建存儲過程:添加學生信息
CREATE PROCEDURE proc_test4 (IN snum CHAR(8),IN sname VARCHAR(20),IN denger CHAR(2),IN age INT,IN tel VARCHAR(20),IN cid INT)
BEGIN
	INSERT INTO students(stu_num,stu_name,stu_denger,stu_age,stu_tel,cid) 	         		VALUES(snum,sname,denger,age,tel,cid);
END;
-- 調用存儲過程
CALL proc_test4('8','張飛','男',88,'13667565656',2);

1.5.2 輸出參數 OUT

將存儲過程中產生的數據,返回給過程調用者,相當于Java的返回值,但不同的是,存儲過程可以有多個輸出參數。

-- 創(chuàng)建存儲過程:根據學號,查詢學生姓名
CREATE PROCEDURE proc_test5(IN snum INT,OUT sname VARCHAR(20))
BEGIN
	SELECT stu_name INTO sname from students where stu_num = snum;
END;
-- 設置用戶參數
SET @name = '';
-- 調用存儲過程
CALL proc_test5(8,@name);
select @name from DUAL;

1.5.3 輸入輸出參數 INOUT

-- 存儲過程:根據學號,查詢學生姓名,使用INOUT
CREATE PROCEDURE proc_test6(INOUT str VARCHAR(20))
BEGIN
	SELECT stu_name INTO str from students where stu_num = str;
END;
-- 設置參數,默認賦值為查詢參數值
set @str = '8';
-- 調用存儲過程
CALL proc_test6(@str);
SELECT @str from dual;

1.6 存儲過程中的流程控制

在存儲過程中,支持流程控制語句用于實現邏輯的控制

1.6.1 分支語句

if-then-else

單分支:

– 單分支:如果條件成立,則執(zhí)行SQL
CREATE PROCEDURE test7(IN a INT)
BEGIN
IF CONDITION THEN
– SQL
END IF;
END;

雙分支

– 雙分支:如果條件成立,則執(zhí)行SQL1;否則,執(zhí)行SQL2
CREATE PROCEDURE test7(IN a INT)
BEGIN
IF CONDITION THEN
– SQL1
ELSE
– SQL2
END IF;
END;

case

– CASE
CREATE PROCEDURE proc_test8(IN a INT)
BEGIN
CASE a
WHEN 1 THEN – 參數a = 1 時,執(zhí)行SQL1
– SQL1
WHEN 2 THEN – 參數a = 2 時,執(zhí)行SQL2
– SQL2
ELSE
– SQL3 – 如果變量值和所有的when值都不匹配,則執(zhí)行SQL3
END CASE;
END;

1.6.2 循環(huán)語句

while

– 創(chuàng)建存儲過程:添加參數,按照參數值,創(chuàng)建班級信息,即參與為3,就創(chuàng)建3條班級信息
CREATE PROCEDURE proc_test7(IN num INT)
BEGIN
DECLARE i INT; – 局部變量
SET i = 0;
WHILE i<num DO – i < 參數變量時,循環(huán)執(zhí)行SQL語句
– SQL
SET i = i+1; – 每循環(huán)一次,i增加1
END WHILE;
END;

repeat

– repeat 創(chuàng)建存儲過程:添加參數,按照參數值,創(chuàng)建班級信息,即參與為3,就創(chuàng)建3條班級信息
CREATE PROCEDURE proc_test7(IN num INT)
BEGIN
DECLARE i INT; – 局部變量
SET i = 0;
REPEAT – 循環(huán)執(zhí)行SQL
– SQL
SET i = i+1; – 每執(zhí)行一次,i+1
UNTIL i > num; – UNTIL 判斷后面結果,符合即跳出循環(huán)
END WHILE;
END;

loop

– LOOP 創(chuàng)建存儲過程:添加參數,按照參數值,創(chuàng)建班級信息,即參與為3,就創(chuàng)建3條班級信息
CREATE PROCEDURE proc_test7(IN num INT)
BEGIN
DECLARE i INT; – 局部變量
SET i = 0;
myloop:LOOP – 設置myloop,在myloop中循環(huán)執(zhí)行SQL
– SQL
set i = i+1; – 每循環(huán)一次,i+1
IF i = num THEN – 判斷當i = 參數值時
LEAVE myloop; – 跳出myloop循環(huán)
END IF;
END LOOP;
END;

1.7 存儲過程管理

1.7.1 查詢存儲過程

存儲過程隸屬于某個數據庫的,也就是說,當我們將存儲過程創(chuàng)建在某個數據庫中,只能在當前數據庫中調用,不能跨庫調用

-- 根據數據庫名,查詢當前數據庫中的存儲過程
show PROCEDURE STATUS where db = 'db_test';
-- 查詢存儲過程的創(chuàng)建細節(jié)
SHOW CREATE PROCEDURE db_test.proc_test1;

1.7.2 修改存儲過程

修改存儲過程,主要是指修改存儲過程的特征/特性

alter procedure <proc_name> 特征1 {特征2...}

存儲過程的特征參數

  • CONTAINS SQL 表示子程序包含SQL語句,但不包含讀或寫的數據操作
  • NO SQL 表示子程序不包含SQL語句
  • READS SQL DATA 表示子程序包含讀數據的語句
  • MODIFIES SQL DATA 表示子程序中包含寫數據的語句
  • SQL SECURITY {DEFINER| INVOKER} 指明誰有權限來執(zhí)行
  • DEFINER 定義者才有執(zhí)行權限INVOKER 調用者可以執(zhí)行
  • COMMENT string 表示注釋信息

– 修改存儲過程
ALTER PROCEDURE proc_test1 NO SQL;

1.7.3 刪除存儲過程

刪除存儲過程

-- 刪除存儲過程 DROP
DROP PROCEDURE proc_test1;

二、存儲過程案例

使用存儲過程,完成借書操作

2.1 準備數據

數據庫準備:新建數據庫

## 創(chuàng)建數據庫
create database da_test3;
## 使用數據庫
use db_test3;

數據表及數據準備

-- 創(chuàng)建圖書信息表
CREATE TABLE books(
	book_id INT PRIMARY KEY auto_increment,
	book_name VARCHAR(50) NOT NULL,
	book_author VARCHAR(20) NOT NULL,
	book_price DECIMAL(10,2) NOT NULL,
	book_stock INT NOT NULL,
	book_desc VARCHAR(200)
);
-- 添加圖書信息
INSERT INTO books(book_name,book_author,book_price,book_stock,book_desc) 
VALUES ('Java從入門到放棄','斯蒂芬',28.80,100,'一本帶你從入門到放棄的java頂級教材');
INSERT INTO books(book_name,book_author,book_price,book_stock,book_desc) 
VALUES ('MySQL從入門到放棄','庫里',68.20,20,'一本帶你從入門到放棄的mysql頂級教材');
-- 創(chuàng)建學生信息表
CREATE TABLE students(
	stu_num CHAR(8) PRIMARY KEY,
	stu_name VARCHAR(20) NOT NULL,
	stu_denger CHAR(2) NOT NULL,
	stu_age INT NOT NULL
);
-- 添加學生信息
INSERT INTO students (stu_num,stu_name,stu_denger,stu_age) VALUES('1001','不知火舞','女','20');
INSERT INTO students (stu_num,stu_name,stu_denger,stu_age) VALUES('1002','安其拉','女','25');
INSERT INTO students (stu_num,stu_name,stu_denger,stu_age) VALUES('1003','奕星','男','30');

2.2 創(chuàng)建存儲過程

創(chuàng)建一個存儲過程,實現借書的操作:哪個學生接了哪本數,借書數量

操作:

  • 保存借書記錄
  • 修改圖書庫存

條件:

  • 判斷學生是否存在
  • 判斷圖書是否存在,庫存是否充足

創(chuàng)建借書記錄表

-- 借書記錄表
CREATE TABLE records(
	rid INT PRIMARY KEY auto_increment,
	snum CHAR(4) NOT NULL,
	bid INT NOT NULL,
	borrow_num INT NOT NULL,
	is_return INT NOT NULL,	-- 0-未歸還;1-已歸還
	borrow_date date NOT NULL,
	CONSTRAINT FK_RECORDS_STUDENTS FOREIGN KEY(snum) REFERENCES students(stu_num),
	CONSTRAINT FK_RECORDS_BOOKS FOREIGN KEY(bid) REFERENCES books(book_id)
);

2.2.1 創(chuàng)建存儲過程

-- 實現借書業(yè)務
-- 參數1:	輸入參數	學號	a
-- 參數2:	輸入參數	圖書標號	b
-- 參數3:	輸入參數	借書數量	m
-- 參數4:	輸出參數	借書狀態(tài)(1-借書成功;2-學號不存在;3-圖書不存在;4-庫存不足)
CREATE PROCEDURE proc_borrow_book(IN a CHAR(4),IN b INT,IN m INT,OUT state INT)
BEGIN
	DECLARE stu_count INT DEFAULT 0;	
	DECLARE b_count INT DEFAULT 0;
	DECLARE b_stock INT DEFAULT 0;
	-- 一、判斷學號是否存在	根據參數a去學生表查詢是否存在學生
	SELECT COUNT(stu_num) INTO stu_count from  students where stu_num = a;
	IF stu_count > 0 THEN
		-- 學號存在
		-- 二、查看圖書編號是否存在
		SELECT COUNT(book_id) INTO b_count from books where book_id = b;
		IF b_count > 0 THEN
			-- 圖書存在
			-- 三、查詢圖書庫存是否充足
			SELECT book_stock INTO b_stock from books where book_id = b;
			IF b_stock >= m THEN
				-- 庫存滿足
				-- 1、插入借書記錄表
				INSERT INTO records(snum,bid,borrow_num,is_return,borrow_date) VALUES(a,b,m,0,SYSDATE());
				-- 2、更新books表庫存數據book_stock
				UPDATE books SET book_stock = (b_stock - m) where book_id = b;
				-- 3、借書成功,返回成功狀態(tài) 0 
				SET state = 1;
			ELSE
				-- 庫存不足
			SET state = 4;
			END IF;
		ELSE
			-- 圖書不存在
		SET state = 3;
		END IF;
	ELSE
		-- 學號不存在
	SET state = 2;
	END IF;
END;

2.2.2 測試

SELECT * FROM students;-- 學生表
select * from books;-- 圖書表
select * from records;-- 借書記錄表
-- 測試借書存儲過程
-- 1、正常借書成功業(yè)務測試:學生學號a = 1001;借書編號b = 1;借書數量m = 10;
SET @state = 0;
CALL proc_borrow_book('1001',1,10,@state);
SELECT @state from DUAL;
-- 2、測試學號不存在:學生學號a = 1008;借書編號b = 1;借書數量m = 10;
SET @state = 0;
CALL proc_borrow_book('1008',1,10,@state);
SELECT @state from DUAL;
-- 3、測試圖書編號不存在:學生學號a = 1002;借書編號b = 8;借書數量m = 10;
SET @state = 0;
CALL proc_borrow_book('1002',8,10,@state);
SELECT @state from DUAL;
-- 4、測試圖書庫存不足:學生學號a = 1002;借書編號b = 2;借書數量m = 100;
SET @state = 0;
CALL proc_borrow_book('1002',2,100,@state);
SELECT @state from DUAL;

到此這篇關于MySQL存儲過程的創(chuàng)建和使用的文章就介紹到這了,更多相關MySQL存儲過程使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • PHP MYSQL注入攻擊需要預防7個要點

    PHP MYSQL注入攻擊需要預防7個要點

    這篇文章主要介紹了PHP MYSQL開發(fā)中,對于注入攻擊需要預防的7個要點,大家需要注意了
    2013-11-11
  • C#編寫方法實例

    C#編寫方法實例

    在下面的練習中,將創(chuàng)建一個應用程序,它包含的一個方法能夠計算一名顧問的收費金額——假定該顧問每天收取固定的費用,將根據工作了多少天來收費。首先要開發(fā)應用程序的邏輯,然后利用“生成方法存根向導”來寫出這個邏輯使用的方法。接著,我們將在一個控制臺應用程序中運行方法,以獲得對該程序的最終印象。最后,我們將使用Visual Studio 2005調試器來檢查方法調用。
    2008-04-04
  • MySQL之FIELD()與ORDER BY()相結合實現對結果的自定義排序方式

    MySQL之FIELD()與ORDER BY()相結合實現對結果的自定義排序方式

    這篇文章主要介紹了MySQL之FIELD()與ORDER BY()相結合實現對結果的自定義排序方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Linux如何添加mysql系統環(huán)境變量

    Linux如何添加mysql系統環(huán)境變量

    這篇文章主要介紹了Linux如何添加mysql系統環(huán)境變量問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 淺談MySQL timestamp(3)問題

    淺談MySQL timestamp(3)問題

    本文主要介紹了淺談MySQL timestamp(3)問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • 一條 SQL 語句執(zhí)行過程

    一條 SQL 語句執(zhí)行過程

    這篇文章主要介紹了一條 SQL 語句執(zhí)行過程的相關資料,沒人詳細具有一的的參考價值,需要的小伙伴可以參考一下,希望對你的學習和工作有所幫助
    2022-03-03
  • 解讀MySQL中一個B+樹能存儲多少數據

    解讀MySQL中一個B+樹能存儲多少數據

    這篇文章主要介紹了解讀MySQL中一個B+樹能存儲多少數據的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • mysql百萬數據表加索引優(yōu)化的方法

    mysql百萬數據表加索引優(yōu)化的方法

    在大數據時代,隨著數據量的快速增長,對數據庫的索引優(yōu)化變得尤為重要,本文主要介紹了mysql百萬數據表加索引優(yōu)化的方法,感興趣的可以了解一下
    2024-02-02
  • MySQL數據庫表的合并及分區(qū)方式

    MySQL數據庫表的合并及分區(qū)方式

    這篇文章主要介紹了MySQL數據庫表的合并及分區(qū)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • mysql全量備份、增量備份實現方法

    mysql全量備份、增量備份實現方法

    這篇文章主要介紹了mysql全量備份、增量備份實現方法,需要的朋友可以參考下
    2016-12-12

最新評論