函數是作為表達式調用的獨立SPL程序。進行求值后,函數返回一個值,該值在該函數所嵌入的表達式中被替換。函數可以選擇以輸入參數的形式從調用程序獲取值。除了函數實際上本身返回值之外,函數還可以選擇以輸出參數的形式向調用方返回其他值。不過,在函數中使用輸出參數并不是提倡的編程做法。
CREATE FUNCTION命令定義并命名一個將存儲在數據庫中的獨立函數。
如果包括Schema名稱,則在指定Schema中創建函數,否則在當前Schema中創建。對于任何現有函數,如果與新函數在相同的Schema中具有相同的輸入參數類型,則新函數名稱不能與現有函數名稱匹配。不過,具有不同輸入參數類型的函數可共用一個名稱(這稱為重載)。
函數重載是PolarDB PostgreSQL版(兼容Oracle)的一項功能,重載已存儲的獨立函數這一功能與Oracle數據庫不兼容。
如需更新現有函數的定義,請使用CREATE OR REPLACE FUNCTION
。但無法以此方式更改函數的名稱或參數類型(如果您嘗試過此方式,實際上創建的是一個新的不同函數)。此外,CREATE OR REPLACE FUNCTION
無法更改現有函數的返回類型,如需更改現有函數的返回類型,必須刪除并重新創建函數。此外,在使用OUT參數時,除非通過刪除函數,否則您不能更改任何OUT參數的類型。
CREATE [ OR REPLACE ] FUNCTION name [ (parameters) ]
RETURN data_type
[
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是形參的列表。 |
data_type | data_type是函數的RETURN語句所返回值的數據類型。 |
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 | AUTHID DEFINER子句是[EXTERNAL] SECURITY DEFINER的同義詞。如果省略AUTHID子句或者指定了AUTHID DEFINER,則使用函數所有者的權限來確定對數據庫對象的訪問特權。 AUTHID CURRENT_USER子句是[EXTERNAL] SECURITY INVOKER的同義詞。如果指定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 FUNCTION simple_function
RETURN VARCHAR2
IS
BEGIN
RETURN 'That''s All Folks!';
END simple_function;
以下函數采用兩個輸入參數。參數將在后面的章節中更詳細地講述。
CREATE OR REPLACE FUNCTION emp_comp (
p_sal NUMBER,
p_comm NUMBER
) RETURN NUMBER
IS
BEGIN
RETURN (p_sal + NVL(p_comm, 0)) * 24;
END emp_comp;
以下示例演示了如何在函數聲明中使用 AUTHID CURRENT_USER 子句和 STRICT 關鍵字:
CREATE OR REPLACE FUNCTION dept_salaries(
dept_id int
) RETURN NUMBER
STRICT
AUTHID CURRENT_USER
AS
BEGIN
RETURN (SELECT sum(sal) FROM emp WHERE deptno = dept_id);
END;
包括STRICT關鍵字以指示在傳遞的任意輸入參數為NULL時,服務器返回NULL;如果傳遞了NULL值,則不執行函數。
dept_salaries函數使用調用該函數的角色的特權執行。如果當前用戶沒有足夠的特權來執行查詢emp表的SELECT語句(以顯示員工工資),則函數將報告錯誤。要指示服務器使用與定義了函數的角色關聯的特權,可將AUTHID CURRENT_USER子句替換為AUTHID DEFINER子句。