20 存储过程
一、存儲過程的定義
存儲過程是存儲在數據庫目錄中的一坨的聲明性SQL語句。 Java,Python,PHP等應用程序可以調用存儲過程。MySQL是最受歡迎的開源RDBMS,被社區和企業廣泛使用。 然而,在它發布的第一個十年期間,它不支持存儲過程,存儲函數,觸發器和事件。自從MySQL 5.0版本以來,這些功能被添加到MySQL數據庫引擎,使其更加靈活和強大。
?
二、存儲過程的優點
#1、通常存儲過程有助于提高應用程序的性能。當創建,存儲過程被編譯之后,就存儲在數據庫中。 但是,MySQL實現的存儲過程略有不同。 MySQL存儲過程按需編譯。 在編譯存儲過程之后,MySQL將其放入緩存中。 MySQL為每個連接維護自己的存儲過程高速緩存。 如果應用程序在單個連接中多次使用存儲過程,則使用編譯版本,否則存儲過程的工作方式類似于查詢。# 2、存儲過程有助于減少應用程序和數據庫服務器之間的流量,因為應用程序不必發送多個冗長的SQL語句,而只能發送存儲過程的名稱和參數。#3、存儲的程序對任何應用程序都是可重用的和透明的。 存儲過程將數據庫接口暴露給所有應用程序,以便開發人員不必開發存儲過程中已支持的功能。#4、存儲的程序是安全的。 數據庫管理員可以向訪問數據庫中存儲過程的應用程序授予適當的權限,而不向基礎數據庫表提供任何權限。除了這些優點之外,存儲過程有其自身的缺點,在數據庫中使用它們之前,您應該注意這些缺點。
三、存儲過程的缺點
#1、如果使用大量存儲過程,那么使用這些存儲過程的每個連接的內存使用量將會大大增加。 此外,如果您在存儲過程中過度使用大量邏輯操作,則CPU使用率也會增加,因為數據庫服務器的設計不當于邏輯運算。#2、存儲過程的構造使得開發具有復雜業務邏輯的存儲過程變得更加困難。#3、很難調試存儲過程。只有少數數據庫管理系統允許您調試存儲過程。不幸的是,MySQL不提供調試存儲過程的功能。#4、開發和維護存儲過程并不容易。開發和維護存儲過程通常需要一個不是所有應用程序開發人員擁有的專業技能。這可能會導致應用程序開發和維護階段的問題。MySQL存儲過程有自己的優點和缺點。開發應用程序時,您應該決定是否應該或不應該根據業務需求使用存儲過程。
四、一個簡單的Mysql存儲過程示例
delimiter //create procedure b1()beginselect * from blog;end // delimiter ;解釋:
1.第一個命令是delimiter //,它與存儲過程語法無關。 delimter語句將標準分隔符 - 分號(;)更改為://。 在這種情況下,分隔符從分號(;)更改為雙斜杠//。為什么我們必須更改分隔符? 因為我們想將存儲過程作為整體傳遞給服務器,而不是讓mysql工具一次解釋每個語句。 在END關鍵字之后,使用分隔符//來指示存儲過程的結束。 最后一個命令(DELIMITER;)將分隔符更改回分號(;)。
2.使用create procedure語句創建一個新的存儲過程。在create procedure語句之后指定存儲過程的名稱。在這個示例中,存儲過程的名稱為:b1,并把括號放在存儲過程的名字之后。
3.begin和end之間的部分稱為存儲過程的主體。將聲明性SQL語句放在主體中以處理業務邏輯。 在這個存儲過程中,我們使用一個簡單的select語句來查詢blog表中的數據。
# mysql中調用存儲過程 call b1()#在python中基于pymysql調用 cursor.callproc('b1') print(cursor.fetchall())?
五、聲明變量
要在存儲過程中聲明變量,可以使用delclare語句,如下
DECLARE variable_name datatype(size) DEFAULT default_value;下面來更詳細地解釋上面的語句:
首先,在DECLARE關鍵字后面要指定變量名。變量名必須遵循MySQL表列名稱的命名規則。
其次,指定變量的數據類型及其大小。變量可以有任何MySQL數據類型,如INT,VARCHAR,DATETIME等。
第三,當聲明一個變量時,它的初始值為NULL。但是可以使用DEFAULT關鍵字為變量分配默認值。
?
實現:
delimiter //create procedure b2()beginDECLARE n int DEFAULT 1;set n = 5;select * from blog where id = n;end // delimiter ;# mysql中調用存儲過程 call b2();?
六、存儲過程傳參
在現實應用中,開發的存儲過程幾乎都需要參數。這些參數使存儲過程更加靈活和有用。 在MySQL中,參數有三種模式:IN,OUT或INOUT。
IN - 是默認模式。在存儲過程中定義IN參數時,調用程序必須將參數傳遞給存儲過程。 另外,IN參數的值被保護。這意味著即使在存儲過程中更改了IN參數的值,在存儲過程結束后仍保留其原始值。換句話說,存儲過程只使用IN參數的副本。
OUT - 可以在存儲過程中更改OUT參數的值,并將其更改后新值傳遞回調用程序。請注意,存儲過程在啟動時無法訪問OUT參數的初始值。
INOUT - INOUT參數是IN和OUT參數的組合。這意味著調用程序可以傳遞參數,并且存儲過程可以修改INOUT參數并將新值傳遞回調用程序。
在存儲過程中定義參數的語法如下:
MODE param_name param_type(param_size)根據存儲過程中參數的目的,MODE可以是IN,OUT或INOUT。
param_name是參數的名稱。參數的名稱必須遵循MySQL中列名的命名規則。
在參數名之后是它的數據類型和大小。和變量一樣,參數的數據類型可以是任何有效的MySQL數據類型
ps:如果存儲過程有多個參數,則每個參數由逗號(,)分隔。
# 1.in delimiter //create procedure b3(in blogName varchar(30))beginselect * from blog where NAME = blogName;end // delimiter ;#mysql中調用存儲過程 call b3('第5篇');#python中調用存儲過程 cursor.callproc('b3',args = ('第5篇')); # 2.out delimiter //create procedure b4(in year int,out count int)beginSELECT COUNT(1) into count FROM blog GROUP BY DATE_FORMAT(sub_time,'%Y') having max(DATE_FORMAT(sub_time,'%Y')) = year ;set count = 6;end // delimiter ;call b4(2016,@count); select @count;#out只能當返回值# 3.inoutdelimiter //create procedure b5(inout n1 int)beginselect * from blog where id > n1;end // delimiter ;#mysql中調用set @n = 3;
call b5(@n);
select @n;
#在python中基于pymysql調用 cursor.callproc('b5',(4)) print(cursor.fetchall()) #查詢select的查詢結果cursor.execute('select @n1') print(cursor.fetchall()) # inout:既可以傳入又可以返回
?
轉載于:https://www.cnblogs.com/lingcai/p/10001710.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: 第二阶段冲刺10
- 下一篇: DB 数据同步到数据仓库的架构与实践