MySQL預存程序

來源:互聯網
上載者:User

標籤:方法   limit   bool   sof   類型   ref   迴圈   依次   roo   

含義

預存程序類似一個函數,資料庫中也支援迴圈語句和判斷語句。我們可以將所有的邏輯、判斷和SQL語句全部寫在資料庫上面,然後取個名字,當程式來操作的時候,可以直接通過這個名字,就能執行對應的功能;不用傳大量的SQL語句。

 

預存程序

一、建立預存程序

關鍵字: procedure

代碼:

create procedure proc_p1()

說明:

  • create procedure:表示要建立儲存。
  • proc_p1:是建立儲存的名字。

這樣就建立了一個預存程序,名為proc_p1;但是此時裡面並沒內容。

二、建立預存程序內容

代碼:

create procedure proc_p1()begin內容置放位置end

說明:
要操作的內容必須放在,begin和end之間。

案例:

資料庫內容:

作業碼:

create procedure proc_p1()BEGINselect * from part;END

結果;產生的對象會儲存在函數中;

三、調用預存程序

關鍵字:CALL

代碼:

CALL proc_p1();

四、刪除預存程序

代碼:

drop procedure proc_p1;

問題:能否修改預存程序那?

答案是肯定的,但是卻很繁瑣,因此我們一般修改的時候,都是重寫預存程序。

因此,針對修改我們的操作(也是重寫):

delimiter $$drop procedure proc_p1 $$create procedure proc_p1()BEGIN  select * from part;END $$delimiter ;
代碼

分析:
即先刪除,後寫入。

問題:如果刪除的時候,沒有對應的預存程序那?

答案:會報錯!
因此我們要避險這種情況出現。

delimiter $$drop procedure if EXISTS proc_p1 $$create procedure proc_p1()BEGIN  select * from part;END $$delimiter ;
代碼

分析:
增加了if EXISTS判斷;它表示,如果後面的這個預存程序有則刪除,反之不操作;這樣避免報錯,導致問題。

上面的代碼都是簡單的操作,再看下面的代碼:

 

有參數的預存程序

一、參數 in

delimiter $$drop procedure if EXISTS proc_p1 $$create procedure proc_p1(  in i1 int)BEGINdeclare d1 int;declare d2 int default 2;set d1 = i1 + d2;END $$delimiter ;
in

分析:
in:表示進的,接收參數
declare:表示聲變數。
int:表示變數類型
default:表示設定變數的初始值。
set:表示賦值操作,也可以理解為設定值。

自訂代碼的結束符號

delimiter

drop procedure if EXISTS proc_p1;create procedure proc_p1()BEGINselect * from part;END

上面代碼在Navicat下是能執行的,但是在終端上是要出問題的。
原因就是這個分號;上面的代碼begin和end間代碼,表示一個功能,都是整體傳進去的,但是,代碼在執行的時候,遇到分號;則表示此功能的代碼執行完畢。所以導致後面的代碼不執行,在終端的運行,因為分號的原因,會導致啟動並執行時候出問題,所以,分號要是用在不對的位置,會造成很大的麻煩。

說明:
這個的意思就表示,以後的mysql語句都是以 $$為結束。

注意:

自訂的時候不能將 \\ 設定用來結束;\\ 在終端會報錯!可能是轉義符的原因吧。

驗證上面的說明:

在終端進入mysql用戶端,當我們輸入的代碼不帶分號的時候,結果,會一直處於等待命令的狀態:

 

加上分號:出結果

問題:如果我們這樣改動的話,獲導致全域都受影響,因此我們可以讓這種效果,只在指定範圍有效,離開這個範圍,有還原會之前?

所以,完整的代碼:

delimiter $$drop procedure if EXISTS proc_p1 $$create procedure proc_p1(in i1 int)BEGINdeclare d1 int;declare d1 int;set d1 = i1 + d2;END $$delimiter ;
完整代碼

說明:

我們在end後加上 $$ 表示一個功能的代碼結束,並在最後,又將設定還原會去。還是以分號結尾,這樣其他代碼不受影響

 

下面接著儲存參數in分析

二、參數 out

代碼:

delimiter $$drop procedure if EXISTS proc_p1 $$create procedure proc_p1(in i1 int,out i2 int)BEGINdeclare d2 int default 3;if i1 = 1 thenset i2 = 100 + d2;elseif i1 = 2 THENset i2 = 200 + d2;elseset i2 = 1000 + d2;end if;END $$delimiter ;-- 加入回話變數 @u;call proc_p1(1, @u);select @u;
out

結果:

  • 說明:
    @u:預設其值為 none;回話變數,相當於我們在外面建立了一個變數,並將引用傳入 proc_p1函數,這個傳入的引用會被 i2 接收,所以,間接的也相當於在給這個 @u 賦值。
  • out:字面意思理解,出;有返回的意思。

三、參數 inout

delimiter $$drop procedure if EXISTS proc_p1 $$create procedure proc_p1(in i1 int,inout ii int,out i2 int)BEGINdeclare d2 int default 3;if i1 = 1 thenset i2 = 100 + d2;set ii = ii + 1;elseif i1 = 2 THENset i2 = 200 + d2;elseset i2 = 1000 + d2;end if;END $$delimiter ;-- 加入回話變數 @u;set @o = 5;call proc_p1(1, @o, @u);select @o,@u;
inout

結果:

分析:
inout:從字面意思理解”進、出”,表示要接收一個帶值的變數,同時函數執行完後,也會將對應的變數返回。

擴充:sql中@變數

帶上一個@叫使用者變數:只要使用者還登入著,這個變數就有效;不管在那個代碼塊中都有效;除非使用者被關閉。

帶上2個@叫全域變數。

注意:使用者變數和函數的局部變數的區別

  • 使用者變數:只要使用者還登入著,這個變數就有效;不管在那個代碼塊中都有效;除非使用者被關閉。
  • 局部變數:離開函數就沒用了。
python操作資料庫預存程序
#!/usr/bin/env python# -*- coding:utf-8 -*-import pymysqlconn = pymysql.connect(host=‘127.0.0.1‘, port=3306, user=‘root‘, passwd=‘123‘, db=‘t1‘)cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)# 執行預存程序cursor.callproc(‘proc_p1‘, (1,2,3))# 擷取執行完儲存的參數cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")result = cursor.fetchall()conn.commit()cursor.close()conn.close()print(result)
代碼

說明:
cursor.callproc(‘proc_p1’, (1,2,3)):只能給資料庫中的proc_p1儲存方法;根據前面的我們知道資料庫中的proc_p1;只能接收2個參數,所以,即使你傳入了3個也只有2個能用。後面的會自動忽略。

上面的資料庫中的預存程序,沒有SQL語句,只是簡單的,變數操作,但是,如果我們加入SQL操作,那我們在python中怎樣擷取這個SQL語句操作的結果那?

 

擷取預存程序的查詢結果:

cursor.fetchall()

 問題:怎樣擷取變數的傳回值那?

cursor.execute("select @_p1_0”)

分析:
1、首先要用select
2、一個@_
3、後面在接預存程序的名字。
4、接 _0:表示索引。表示擷取返回第一個值,要想擷取後面的,則依次往後指定,用逗號隔開便可。

cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")

這個擷取獲的值,存放在遊標裡面的,所以,要擷取具體的值,可以通過遊標結合fetchone擷取:

result = cursor.fetchone()

特殊:
雖然預存程序中,in接收參數,但是在python中擷取預存程序資料的時候,in接收傳入的值,會被返回,所以,擷取的第一個值,便是,callproc執行的時候,傳入的第一個參數.

python擷取預存程序分兩步:

  • 擷取SQL語句執行的傳回值
  • 擷取儲存函數的變數傳回值

 

MySQL預存程序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.