CREATE FUNCTION

Name

CREATE FUNCTION -- 定義一個新函數

Synopsis

 CREATE [ OR REPLACE ] FUNCTION name ( [ [ argname ] argtype [, ...] ] )
    RETURNS rettype
  { LANGUAGE langname
    | IMMUTABLE | STABLE | VOLATILE
    | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
  } ...
    [ WITH ( attribute [, ...] ) ]

描述

CREATE FUNCTION 定義一個新的函數。 CREATE OR REPLACE FUNCTION 將要麼建立一個新函數, 要麼替換現有的定義。

如果包含了一個模式名,那麼函數就在指定的模式中建立。否則它會在目前模式中建立。 新函數的名字不能和同一個模式中的任何帶有同樣參數類型的函數同名。 不過,參數類型不同的函數可以同名(這叫做重載)。

要更新一個現有函數的定義,使用 CREATE OR REPLACE FUNCTION。 我們不能用這個方法修改一個函數的名字或者參數類型(如果您這麼幹,那麼您就會建立一個新的,不同的函數)。 同樣,CREATE OR REPLACE FUNCTION 也不會允許您修改一個現有函數的返回類型。 要做這些事情,您必須刪除並重新建立函數。

如果您刪除然後重建一個函數,新函數和舊的將是不同的實體;您就需要刪除現有引用了老函數的規則,視圖,觸發器等等。 使用 CREATE OR REPLACE FUNCTION 可以在不破壞引用該函數的對象的前提下修改函數定義。

建立這個函數的用戶成為函數的所有者。

參數

name

要建立的函數名字(可以用模式修飾)。

argname

一個參數的名字。有些語言(目前只有 PL/pgSQL)允許您在函數體裡使用參數名字。 對於其它語言,這個參數名字只是額外的文件。

argtype

該函數的資料類型(可以有模式修飾)。 如果有的話,參數類型可以是基本類型,也可以是復合類型,域類型,或者可以引用一個現有字串相同的類型。

根據實現語言的不同,我們還可以在這上面聲明 "偽類型", 比如 cstring。偽類型資料表示實際的參數類型要麼是沒有完整地聲明,要麼是在普通的 SQL 資料類型之外。

一個字串的類型是用 tablename.columnname%TYPE 資料表示的;使用這個東西可以幫助函數獨立於資料表定義的修改。

rettype

返回資料類型。輸出類型可以聲明為一個基本類型,復合類型,域類型, 或者引用一個資料表的現有字串。 根據實現語言的不同,我們還可以在這上面聲明 "偽類型", 比如 cstring

SETOF 修飾詞資料表示該函數將返回一套條目, 而不是一條條目。

一個字串的類型是透過寫 tablename.columnname%TYPE 來引用的。

langname

用以實現函數的語言的名字。 可以是 SQLCinternal,或者是用戶定義的過程語言名字。 為了保持向下兼容,該名字可以用單引號包圍。

IMMUTABLE
STABLE
VOLATILE

這些屬性告訴系統把對該函數的多次調用替換成一次是否安全。 主要用於執行時優化。 至少應該聲明一個選擇。如果任何一個都沒有出現,那麼 VOLATILE 是預設假設。

IMMUTABLE 資料表示該函數在給出同樣的參數值時總是返回相同的結果; 也就是說,它不做資料庫查找或者是使用那些並沒有直接出現在其參數列資料表裡面的訊息。 如果給出這個選項,那麼任何帶著全部是常量參數對該函數的調用都將立即替換為該函數的值。

STABLE 資料表示在一次資料表掃瞄裡,對相同參數值, 該函數將穩定返回相同的值,但是它的結果可能在不同 SQL 語句之間變化。 這個選項對那些結果倚賴資料庫查找,參數變量(比如目前時區),等等的函數是很合適的。 還要注意 current_timestamp 族函數是 stable (穩定)的,因為它們的值在一次交易中不會變化。

VOLATILE 資料表示該函數值甚至可以在一次資料表掃瞄內改變, 因此不會做任何優化。很少資料庫函數在這個概念上是易變的; 一些例子是 random()currval()timeofday()。請注意任何有副作用的函數都必需列為易變類, 即使其結果相當有規律也應該這樣,這樣才能避免它被優化;一個例子就是 setval()

更多細節,請參閱 Section 31.6

CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
STRICT

CALLED ON NULL INPUT (預設)資料表明該函數在自己的某些參數是空值的時候還是可以按照正常的方式調用。 剩下的事情是函數的作者必須負責檢查空值以及相應地做出反應。

RETURNS NULL ON NULL INPUTSTRICT 資料表明如果它的任何參數是 NULL,此函數總是返回 NULL。 如果聲明了這個參數,則如果存在 NULL 參數時不會執行該函數; 而只是自動假設一個 NULL 結果。

[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER

SECURITY INVOKER 資料表明該函數將帶著調用它的用戶的權限執行。 這是預設。SECURITY DEFINER 聲明該函數將以建立它的用戶的權限執行。

關鍵字 EXTERNAL 的目的是和 SQL 兼容, 但是我們和 SQL 不同的是,這個特性不僅僅適用於外部的函數, 所以它是可選的。

definition

一個定義函數的字串常量;含義取決於語言。它可以是一個內部函數名字, 一個指向某個目標文件的路徑,一個 SQL 查詢,或者一個用過程語言寫的文本。

obj_file, link_symbol

這個形式的 AS 子句用於在函數的 C 源文件裡的函數名字和 SQL 函數的名字不同的時候可動態裝載 C 語言函數。 字串 obj_file 是包含可動態裝載的對象的文件名,而 link_symbol 是函數的鏈接符號,也就是該函數在 C 源文件裡的名字。 如果省略了鏈接符號,那麼就假設它和被定義的 SQL 函數同名。

attribute

歷史遺留的函數可選訊息。下面的屬性可以在此出現:

isStrict

等效於 STRICT 或者 RETURNS NULL ON NULL INPUT

isCachable

isCachableIMMUTABLE 的過時的等效物;不過出於向下兼容,我們仍然接受它。

屬性名是大小寫無關的。

注意

請參閱 Section 31.3 獲取更多關於書寫函數的訊息。

我們允許您將完整的 SQL 類型語法用於輸入參數和返回值。 不過,有些類型聲明的細節(比如,numeric 類型的精度域)是由下層函數實現負責的, 並且會被 CREATE FUNCTION 命令悄悄地吞掉。 (也就是說,不再被識別或強制)。

PostgreSQL 允許函數重載; 也就是說,同一個函數名可以用於幾個不同的函數, 只要它們的參數可以區分它們。不過,所有函數的 C 名字必須不同, 也就是說您必須給予重載的 C 函數不同的 C 名字(比如,使用參數類型作為 C 名字的一部分)。

如果重複調用 CREATE FUNCTION,並且都指向同一個目標文件, 那麼該文件只裝載一次。要卸載和恢復裝載該文件(可能是在開發過程中),您可以使用 LOAD 命令。

使用 DROP FUNCTION 刪除一個用戶定義函數。

通常來說,使用美元符包圍(參閱 Section 4.1.2.2)來書寫函數定義字串, 而不是使用普通的單引號包圍語法會方便很多。如果不使用美元符包圍, 那麼函數體裡面的任何單引號或反斜槓都必須用書寫雙份的方法逃逸。

要能定義函數,用戶必須對該語言有 USAGE 權限。

例子

這裡是一個簡單的例子,用於幫助您開始掌握這個命令。 更多訊息和例子,參閱 Section 31.3

CREATE FUNCTION add(integer, integer) RETURNS integer
    AS 'select $1 + $2;'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

PL/pgSQL 自增一個整數,利用參數名:

CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
      BEGIN
              RETURN i + 1;
      END;
$$ LANGUAGE plpgsql;

相容性

在 SQL:1999 裡定義了一個CREATE FUNCTION PostgreSQL 的和它類似但是不兼容。 這個屬性是不可移植的,可以使用的不同語言也是如此。

又見

ALTER FUNCTION, DROP FUNCTION, GRANT, LOAD, REVOKE, createlang