存儲過程是作為單個 SPL 程序語句調用的獨立 SPL 程序。調用時,存儲過程可選擇以輸入參數的形式從調用方接收值,并可選擇以輸出參數的形式向調用方返回值。
CREATE PROCEDURE 命令可定義并命名一個將存儲在數據庫中的獨立存儲過程。
如果包括 schema 名稱,則在指定的 schema 中創建存儲過程。否則在當前 schema 中創建。新存儲過程的名稱不得與同一 schema 中具有相同輸入參數類型的任何現有存儲過程匹配。不過,具有不同輸入參數類型的存儲過程可共用一個名稱(這稱為重載)。(存儲過程重載是一項PolarDB PostgreSQL版(兼容Oracle)功能 - 獨立存儲過程的重載與 Oracle 數據庫不兼容。)
要更新現有存儲過程的定義,可使用 CREATEOR REPLACE PROCEDURE。無法以這種方式更改存儲過程的名稱或參數類型(如果您嘗試過,實際上創建的是一個新的不同存儲過程)。使用 OUT 參數時,除非通過刪除存儲過程,否則不能更改任何 OUT 參數的類型。
CREATE [OR REPLACE] PROCEDURE name [ (parameters) ]
[
IMMUTABLE
| STABLE
| VOLATILE
| DETERMINISTIC
| [ NOT ] LEAKPROOF
| CALLED ON NULL INPUT
| RETURNS NULL ON NULL INPUT
| STRICT
| [ EXTERNAL ] SECURITY INVOKER
| [ EXTERNAL ] SECURITY DEFINER
| AUTHID DEFINER
| AUTHID CURRENT_USER
| PARALLEL { UNSAFE | RESTRICTED | SAFE }
| COST execution_cost
| ROWS result_rows
| SET configuration_parameter
{ TO value | = value | FROM CURRENT }
...]
{ IS | AS }
[ PRAGMA AUTONOMOUS_TRANSACTION; ]
[ declarations ]
BEGIN
statements
END [ name ];
參數 | 說明 |
---|---|
name | name 是存儲過程的標識符。 |
parameters | parameters 是形參的列表。 |
declarations | declarations 是變量、游標、類型或子程序聲明。如果包括子程序聲明,則它們必須在所有其他變量、游標和類型聲明之后。 |
statements | statements 是 SPL 程序語句(BEGIN - END 塊可以包含 EXCEPTION 部分)。 |
IMMUTABLE STABLE VOLATILE | 這些屬性將存儲過程的行為通知給查詢優化器;您只能指定一個選項。VOLATILE 是默認行為。
|
DETERMINISTIC | DETERMINISTIC 是 IMMUTABLE 的同義詞。DETERMINISTIC 存儲過程不能修改數據庫,并在提供相同參數值時始終會得到相同結果;它不執行數據庫查找,也不以其他方式使用其參數列表中不直接存在的信息。如果包括此子句,則使用全常量參數對存儲過程的任何調用將立即替換為存儲過程值。 |
[ NOT ] LEAKPROOF | LEAKPROOF 存儲過程沒有負面影響,也不會公開有關調用存儲過程所用值的任何信息。 |
CALLED ON NULL INPUT RETURNS NULL ON NULL INPUT STRICT |
|
[ EXTERNAL ] SECURITY DEFINER | SECURITY DEFINER 指定存儲過程將使用創建它的用戶的特權來執行;這是默認值。為了符合 SQL 要求,允許使用關鍵字 EXTERNAL,但這是可選的。 |
[ EXTERNAL ] SECURITY INVOKER | SECURITY INVOKER 子句指示存儲過程將使用調用它的用戶的特權執行。為了符合 SQL 要求,允許使用關鍵字 EXTERNAL,但這是可選的。 |
AUTHID DEFINER AUTHID CURRENT_USER |
|
PARALLEL { UNSAFE | RESTRICTED | SAFE } | 通過 PARALLEL 子句可以使用并行順序掃描(并行模式)。在查詢期間,相比串行順序掃描,并行順序掃描使用多個工作線程并行掃描一個關系。
|
COST execution_cost | execution_cost 是一個正數,給出該存儲過程的估計執行成本,單位為 cpu_operator_cost。如果存儲過程返回一個集合,則這是每個返回行的成本。較大值會導致計劃程序嘗試避免超出必要的頻率來對函數求值。 |
ROWS result_rows | result_rows 是一個正數,給出計劃程序預計存儲過程返回的估計行數。僅當存儲過程聲明為返回一個集合時,才允許這么做。默認假定值為 1000 行。 |
SET configuration_parameter { TO value | = value | FROMCURRENT } | SET 子句使指定的配置參數在進入存儲過程時設置為指定值,然后在存儲過程退出時恢復為其之前的值。SET FROM CURRENT 將會話的當前參數值保存為進入存儲過程時要應用的值。 如果將 SET 子句附加到存儲過程,則在存儲過程內針對相同變量執行 SET LOCAL 命令的效果僅限于該存儲過程。存儲過程退出時配置參數將恢復為之前的值。普通的 SET 命令(沒有 LOCAL)會重寫 SET 子句,與對之前 SET LOCAL 命令的操作很相似,此命令的效果在退出存儲過程后會保留,除非回滾當前事務。 |
PRAGMA AUTONOMOUS_TRANSACTION | PRAGMA AUTONOMOUS_TRANSACTION 是將存儲過程設置為自治事務的指令。 |
STRICT、LEAKPROOF、PARALLEL、COST、ROWS 和 SET 關鍵字可以為PolarDB PostgreSQL版(兼容Oracle)提供擴展功能,但 Oracle 不支持這些關鍵字。
示例
下面是一個不采用參數的簡單存儲過程的示例。
CREATE OR REPLACE PROCEDURE simple_procedure
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('That''s all folks!');
END simple_procedure;
通過在PolarDB PostgreSQL版(兼容Oracle)中輸入存儲過程代碼,將該存儲過程存儲在數據庫中。
以下示例演示了如何在存儲過程聲明中使用 AUTHID DEFINER 和 SET 子句。update_salary 存儲過程將定義了該存儲過程的角色的特權傳遞給正在調用該存儲過程的角色(在執行該存儲過程時):
CREATE OR REPLACE PROCEDURE update_salary(id INT, new_salary NUMBER)
SET SEARCH_PATH = 'public' SET WORK_MEM = '1MB'
AUTHID DEFINER IS
BEGIN
UPDATE emp SET salary = new_salary WHERE emp_id = id;
END;
包括 SET 子句,將存儲過程的搜索路徑設置為 public,并將工作內存設置為 1MB。其他存儲過程、函數及對象不受這些設置的影響。
在此示例中,AUTHID DEFINER 子句將特權臨時授予可能不允許執行存儲過程內語句的角色。要指示服務器使用與調用存儲過程的角色相關聯的特權,可將 AUTHID DEFINER 子句替換為 AUTHID CURRENT_USER 子句。