用PL pgSQL寫postgreSQL的儲存過程

2021-05-23 16:26:45 字數 3023 閱讀 5996

今天學會了用 pl/pgsql 寫 postgresql 的儲存過程,網上資料實在少得可憐,唯一能搜到的一些還是抄來抄去的;還是翻postgresql的文件吧,把今天解決的問題說一下吧,希望對其他人有幫助。

問題是這樣的,有一張message表:

create table message

(id int8 not null,

receiveuserid int8,

senduserid int8,

receivedelete bool default false,

senddelete bool default false,

……constraint usermessage_pkey primary key (id)

)略去其他字段,senduserid是發資訊的使用者id,senddelete如為true則表示這條訊息被發信人所刪除;至於receive我就不用說了。一條資訊只有被發信人和收信人都刪除,才能真正從表裡刪除(這是顯然的,否則收信人刪了一條訊息後,發信人的「發件箱」裡就會找不到這條訊息)。

所以刪除訊息(可能是多條訊息)的時候要進行各種判斷(是否是發信人?是否是收信人?是否真正刪除?),用單條sql語句完成這個工作顯然有些困難(當然用迴圈巢狀select不考慮效率的話也是可以實現的),只好寫儲存過程了。

順便介紹常用的pl/pgsql結構和語法吧:

結構 pl/pgsql是一種塊結構的語言,比較方便的是用pgadmin iii新建function,填入一些引數就可以了。基本上是這樣的:

create or replace function 函式名(引數1,[整型 int4, 整型陣列 _int4, …])

returns 返回值型別 as

$body$

declare

變數宣告

begin

函式體end;

$body$

language 『plpgsql』 volatile;

變數型別

除了postgresql內建的變數型別外,常用的還有 record ,表示一條記錄。

賦值 賦值和pascal有點像:「變數 := 表示式;」

有些奇怪的是連線字串的是「||」,比如 sql := 『select * from』 || table || 『where …』;

判斷 判斷又和vb有些像:

if 條件 then

…elseif 條件 then

…else

…end if;

迴圈 迴圈有好幾種寫法:

while expression loop

statements

end loop;

還有常用的一種是:(從1迴圈到9可以寫成for i in 1..9 loop)

for name in [ reverse ] expression .. expression loop

statements

end loop;

其他 還有幾個常用的函式:

select into record …; 表示將select的結果賦給record變數(record型別)

perform query; 表示執行query並丟棄結果

execute sql; 表示執行sql語句,這條可以動態執行sql語句(特別是由引數傳入構造sql語句的時候特別有用)

最後,貼出解決上面這個問題的儲存過程吧:

create or replace function message_deletes ( ids " varchar " , userid int8 )

returns   int4 as

$ body $

declare

r   record ;

del   bool ;

num   int4 := 0 ;

sql   " varchar " ;

begin

sql := ' select id,receiveuserid,senduserid,senddelete,receivedelete from message where id in ( ' || ids || ' ) ' ;

for   r in execute sql loop

del := false ;

if   r . receiveuserid = userid and r . senduserid = userid then

del := true ;

elseif   r . receiveuserid = userid then

if   r . senddelete = false then

update   message set receivedelete = true where id = r . id ;

else

del := true ;

end   if ;

elseif   r . senduserid = userid then

if   r . receivedelete = false then

update   message set senddelete = true where id = r . id ;

else

del := true ;

end   if ;

end   if ;

if   del then

delete   from message where id = r . id ;

num := num + 1 ;

end   if ;

end   loop ;

return   num ;

end ;

$ body $

language   ' plpgsql ' volatile ;

測試使用:

alter function updateuseraccout(userid integer,nmoney integer)owner to armory;

意思為:讓armory使用者擁有使用updateuseraccout函式的許可權

用yaml寫用例

第一步 安裝yaml,在執行裡輸入 pip install pyyaml 檢驗是否安裝成功,在pycharm裡輸入 import yaml 第二步 建立乙個file,字尾寫yaml或yml 在yml檔案裡寫入單個使用者名稱和密碼 開啟yml檔案並以字典的形式列印出來 執行結果 在yml檔案裡寫入多個...

用VC寫執行緒

handle hworkthread hworkthread createthread null,0,lpthread start routine startworkthread,執行緒入口函式 info,傳遞引數給執行緒入口函式 0,null 其中startworkthread為執行緒主函式,其必...

用gridview寫分頁

根據pagecount和pageindex實現分頁功能以及刪除提示 protected void gridview1 rowcreated object sender,gridviewroweventargs e if e.row.rowtype datacontrolrowtype.pager i...