Postgresql 儲存過程(plpgsql)兩層for迴圈的操作
專案中遇到測試,需要造4500資料,而且需要分部門和日期,一個部門一天30條資料,剩下的鋪墊資料可以一個部門一天100w左右資料,這裡,每次變換部門,日期,需要操作至少300次,想到用儲存過程寫一個函式進行
首先,瞭解儲存過程的語法:
CREATE [ OR REPLACE ] FUNCTION name( [ [argmode] [argname]argtype[ { DEFAULT | = }default_expr] [,...] ] ) [ RETURNSrettype | RETURNS TABLE (column_namecolumn_type[,...] ) ] { LANGUAGElang_name | WINDOW | IMMUTABLE | STABLE | VOLATILE | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | COSTexecution_cost | ROWSresult_rows | SETconfiguration_parameter{ TOvalue| =value| FROM CURRENT } | AS 'definition' | AS 'obj_file','link_symbol' } ... [ WITH (attribute[,...] ) ] ————————————————
CREATE [ OR REPLACE ] FUNCTION--建立一個函式,若有此函式,即取代重新建立 name -------函式名稱
RETURNS---函式返回型別
具體的函式宣告,請參考[postgresql儲存過程]
下面說我寫的函式:
CREATE OR REPLACE FUNCTION "xue"."insert_into_table"() RETURNS "pg_catalog"."void" AS $BODY$ DECLARE tmp VARCHAR(1024); DECLARE n integer; DECLARE i integer; DECLARE inst_seq_no CURSOR FOR SELECT inst_seq_no FROM t where no in ( '111','22','223','33','4358','233','449','315','35335'); BEGIN RAISE NOTICE '------------start----------'; i := 30; FOR stmt IN no LOOP n := 30; FOR n IN n..i LOOP insert into test2 (NO,test_NO,TIME,USER_NO,SEQ_NO,NAME,USER_NO1,USER_NAME,CODE,USER_NO2,OPROR_NAME,REVIEW_TIME,DESC,VAL1,VAL2,DATE,UPD_TIME,DEL_FLAG) values (nextval('seq_test2'),n,'20190910',stmt.seq_no,'01','','20190909','0'); END LOOP; n = n+30; i = i+30; END LOOP; RAISE NOTICE '-----------finished---------'; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100`
很簡單的邏輯,但是在修改了三四遍才實現,這個第二次寫儲存過程,很多語法不是很熟悉,要注意的如:
1.`變數宣告要用DECLARE
2.``遊標 CURSOR 的用法
3.for迴圈要在begin中執行,
4.迴圈中要用“:=”
補充:Postgresql中儲存過程(函式)呼叫儲存過程(函式)時應用注意的問題
在postgresql中我們在執行儲存過程中往往會使用select 儲存過程,但是如果儲存過程中再呼叫 儲存過程時,就不能這樣用了,應該用perform 儲存過程,可以去參考官方文件的說明
執行一個沒有結果的表示式或者命令
有時候我們希望計算一個表示式或者一個命令,但是卻丟棄其結果(通常因為我們經常呼叫一些存在有用的副作用但是不存在有用結果值的函式)。 要在 PL/pgSQL 裡幹這件事, 你可以使用PERFORM語句:
PERFORM query;
這條語句執行一個 query並且丟棄結果。 query 的寫法和你平常寫 SQL SELECT 命令是一樣的, 只是把開頭的關鍵字 SELECT 替換成 PERFORM。 PL/pgSQL 的變數和平常一樣代換到命令中。 同樣,如果命令生成至少一行,那麼特殊的變數 FOUND 設定為真,如果沒有生成行,則為假。
注意: 我們可能希望沒有INTO子句的SELECT也能滿足這樣的需要, 但是目前可以接受的唯一的方法是PERFORM。
一個例子:
PERFORM create_mv('cs_session_page_requests_mv',my_query);
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。