Python全棧之路系列之MySQL存儲過程
存儲過程是一個SQL語句集合,當主動去調用存儲過程時,其中內部的SQL語句會按照邏輯執行。
存儲過程過接收的參數
參數 | 描述 |
---|---|
in | 僅用於傳入參數用 |
out | 僅用於返回值用 |
inout | 既可以傳入又可以當作返回值 |
創建存儲過程
創建一個簡單的存儲過程
-- 修改SQL語句的結束符爲% delimiter % -- 創建這個存儲過程先刪除 DROP PROCEDURE IF EXISTS proc_p1 % CREATE PROCEDURE proc_p1() -- 開始 BEGIN -- SQL語句塊 select * from color; -- 結束 END % -- 把SQL語句的結束符改爲; delimiter ;
通過call
調用存儲過程
call proc_p1();
輸出爲
+-----+--------+ | nid | title | +-----+--------+ | 1 | red | | 2 | yellow | +-----+--------+ 2 rows in set (0.00 sec) Query OK, 0 rows affected (0.01 sec)
刪除存儲過程
DROP PROCEDURE proc_p1;
實例
創建一個存儲過程,接收一個參數,傳入的參數就是顯示數據的個數,
delimiter % DROP PROCEDURE IF EXISTS proc_p1 % create PROCEDURE proc_p1( -- i1就是傳入的參數,傳入的數據類型必須是int類型 in i1 int ) BEGIN -- 定義兩個局部變量d1和d2,數據類型都爲int,d1默認值爲空,d2默認值爲1 DECLARE d1 int; DECLARE d2 int DEFAULT 1; -- d1的值等於傳入過來的i1加上定義的局部變量d2的值 SET d1 = i1 + d2; -- 查找person_info表中的nid大於d1的數據 SELECT * FROM person_info WHERE nid > d1; END % delimiter ;
查詢,括號內輸入定義的參數
CALL proc_p1(4);
顯示結果
+-----+------+------------------+-------------+----------+----------+---------+-----------+ | nid | name | email | phone | part_nid | position | caption | color_nid | +-----+------+------------------+-------------+----------+----------+---------+-----------+ | 6 | w | [email protected] | 13800138000 | 5 | Python | NULL | NULL | | 9 | aa | [email protected] | 13800138000 | 3 | DBA | NULL | 2 | | 10 | b | b.ansheng.me | 13800138000 | 3 | DBA | NULL | 1 | +-----+------+------------------+-------------+----------+----------+---------+-----------+ 3 rows in set (0.00 sec) Query OK, 0 rows affected (0.01 sec)
這次把nid
大於5
的數據全部輸出出來了,傳入的值是4
,我們在內部讓4+1
了,所以就是大於5
的數據.
delimiter % DROP PROCEDURE IF EXISTS proc_p1 % create PROCEDURE proc_p1( -- 接收了三個參數,類型都是int in i1 int, inout ii int, out i2 int ) BEGIN -- 定義一個局部變量d2,默認值是3,數據類型爲int DECLARE d2 int DEFAULT 3; -- ii = ii + 1 set ii = ii + 1; -- 如果傳入的i1等於1 IF i1 = 1 THEN -- i2 = 100 + d2 set i2 = 100 + d2; -- 如果傳入的i1等於2 ELSEIF i1 = 2 THEN -- i2 = 200 + d2 set i2 = 200 + d2; -- 否則 ELSE -- i2 = 1000 + d2 set i2 = 1000 + d2; END IF; END % delimiter ;
查看數據
set @o = 5; CALL proc_p1(1,@o,@u); SELECT @o,@u;
顯示的結果
+------+------+ | @o | @u | +------+------+ | 6 | 103 | +------+------+ 1 row in set (0.00 sec)
使用pymysql模塊操作存儲過程
Python代碼爲:
import pymysql conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd='as', db="dbname") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 執行存儲過程 row = cursor.callproc("proc_p2",(1,2,3)) # 存儲過程的查詢結果 selc = cursor.fetchall() print(selc) # 獲取存儲過程返回 effect_row = cursor.execute('select @_proc_p2_0, @_proc_p2_1, @_proc_p2_2') # 取存儲過程返回值 result = cursor.fetchone() print(result) conn.commit() cursor.close() conn.close()
顯示的結果
C:\Python\Python35\python.exe D:/PycharmProjects/pymysql_存儲過程.py [{'nid': 1, 'name': 'man1'}, {'nid': 2, 'name': 'man2'}, {'nid': 3, 'name': 'man3'}] {'@_proc_p2_1': 3, '@_proc_p2_0': 1, '@_proc_p2_2': 103} Process finished with exit code 0
存儲過程使用into
into
其實就是把一個select
的執行結果當作另一個select
的參數,例如下面的實例:
delimiter % DROP PROCEDURE IF EXISTS proc_p2 % CREATE PROCEDURE proc_p2() BEGIN -- 定義一個局部變量n,類型爲int DECLARE n int; -- 獲取color_nid = 2的數據並賦值給n SELECT color_nid into n FROM person_info where color_nid = 2; -- 輸出nid = n的數據 SELECT * from color WHERE nid = n; END % delimiter ;
執行
call proc_p2();
結果
+-----+--------+ | nid | title | +-----+--------+ | 2 | yellow | +-----+--------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.01 sec)