CREATE FUNCTION - Amazon Redshift

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

CREATE FUNCTION

使用子SQLSELECT句或 Python 程式建立新的純量使用者定義函數 (UDF)。

如需詳細資訊和範例,請參閱 Amazon Redshift 中的使用者定義函數

所需權限

您必須具有下列其中一種執行 CREATE OR REPLACE 的許可FUNCTION:

  • 對於 CREATE FUNCTION:

    • 超級使用者可以使用受信任和不受信任的語言來建立函數。

    • 具有 CREATE【 OR 】 REPLACE FUNCTION權限的使用者可以使用受信任的語言建立函數。

  • 對於 REPLACE FUNCTION:

    • 超級使用者

    • 具有 CREATE【 OR 】 REPLACE FUNCTION權限的使用者

    • 函數擁有者

語法

CREATE [ OR REPLACE ] FUNCTION f_function_name ( { [py_arg_name py_arg_data_type | sql_arg_data_type } [ , ... ] ] ) RETURNS data_type { VOLATILE | STABLE | IMMUTABLE } AS $$ { python_program | SELECT_clause } $$ LANGUAGE { plpythonu | sql }

參數

或 REPLACE

指定已有相同名稱和輸入引數資料類型 (或簽章) 的函數存在時,取代現有函數。您可以將函數取代為定義一組相同資料類型的新函數。您必須是超級使用者才能取代函數。

如果您定義的函數與現有函數同名,但簽章不同,則會建立新函數。換言之,函數名稱將會過載。如需詳細資訊,請參閱多載函數名稱

f_function_name

函數的名稱。如果您指定結構描述名稱 (例如 myschema.myfunction),則會使用指定的結構描述建立函數。否則,函數會在目前結構描述中建立。如需有效名稱的相關資訊,請參閱 名稱與識別碼

建議您使用 在所有UDF名稱前面加上 f_。Amazon Redshift 保留UDF名稱的f_字首,因此使用f_字首,您可以確保UDF您的姓名不會與任何現有或未來的 Amazon Redshift 內建SQL函數名稱衝突。如需詳細資訊,請參閱防止UDF命名衝突

若輸入引數的資料類型不同,則您可以定義多個擁有相同函數名稱的函數。換言之,函數名稱將會過載。如需詳細資訊,請參閱多載函數名稱

py_arg_name py_arg_data_type | sql_arg_data_type

對於 Python UDF,輸入引數名稱和資料類型的清單。對於 SQL UDF,列出沒有引數名稱的資料類型。在 Python 中UDF,使用引數名稱參考引數。在 SQL 中UDF,根據引數清單中的引數順序,使用 $1、$2 等引數。

對於 SQL UDF,輸入和傳回資料類型可以是任何標準 Amazon Redshift 資料類型。對於 Python UDF,輸入和傳回資料類型可以是 SMALLINT、INTEGER、BIGINT、DECIMAL、REAL、DOUBLEPRECISION、、BOOLEANCHAR、VARCHAR、 DATE或 TIMESTAMP。此外,Python 使用者定義函數 (UDFs) 支援資料類型 ANYELEMENT。這會根據執行時提供的對應引數資料類型,自動轉換為標準資料類型。如果多個引數使用 ANYELEMENT,它們都會根據清單中的第一個ANYELEMENT引數,在執行時間解析為相同的資料類型。如需詳細資訊,請參閱 Python UDF 資料類型資料類型

您最多可以指定 32 個引數。

RETURNS data_type

函數所傳回值的資料類型。RETURNS 資料類型可以是任何標準 Amazon Redshift 資料類型。此外,Python UDFs可以使用 的資料類型ANYELEMENT,其會根據執行時提供的引數自動轉換為標準資料類型。如果您ANYELEMENT為傳回資料類型指定 ,則至少有一個引數必須使用 ANYELEMENT。實際傳回資料類型符合呼叫函數時為ANYELEMENT引數提供的資料類型。如需詳細資訊,請參閱Python UDF 資料類型

VOLATILE | STABLE | IMMUTABLE

通知查詢最佳化工具有關函數的波動情形。

如果您將函數標示為最嚴格的有效波動類別,將會得到最理想的最佳化結果。不過,如果類別太嚴格,則最佳化工具可能會錯誤地略過某些呼叫,導致產生不正確的結果集。從最低嚴格程度開始,依嚴格程度排列的波動類別如下所示:

  • VOLATILE

  • STABLE

  • IMMUTABLE

VOLATILE

假設引數相同,即使是針對單一陳述式中的資料列,函數也可能在後續呼叫中傳回不同的結果。查詢最佳化工具無法對波動函數的行為做出任何假設,因此,使用波動函數的查詢必須針對每個輸入資料列重新評估函數。

STABLE

假設引數相同,函數一定會針對單一陳述式內處理的所有資料列傳回相同結果。在不同陳述式中呼叫函數時,函數可能傳回不同結果。此類別可讓最佳化工具將單一陳述式中的多次函數呼叫最佳化,成為陳述式的單一呼叫。

IMMUTABLE

假設引數相同,函數一律傳回相同結果,而且永遠不變。當查詢呼叫具有常數引數的 IMMUTABLE 函數時,最佳化工具會預先評估函數。

AS $$ statement $$

包圍要執行之陳述式的結構。常值關鍵字 AS $$$$ 是必要的。

Amazon Redshift 會要求您使用稱為 $ 符號引用的格式包圍函數中的陳述式。包圍範圍當中的任何內容都會原封不動傳遞。您不需要逸出任何特殊字元,因為字串的內容是逐字撰寫。

使用 $ 符號引用時,您會使用一組 $$ 符號配對表示要執行之陳述式的開頭和結尾,如以下範例所示。

$$ my statement $$

您也可以選擇在每組配對的兩個 $ 符號之間指定字串來協助識別陳述式。您在包圍配對的開頭和結尾中使用的字串必須相同。此字串區分大小寫,且遵循與未加引號的識別碼相同的限制條件,不過後者不可包含 $ 符號。下列範例使用字串 test

$test$ my statement $test$

如需美元報價的詳細資訊,請參閱 PostgreSQL 文件的 Lexical Structure 下的「美元報價字串常數」。

python_program

傳回值的有效可執行 Python 程式。隨函數傳入的陳述式必須符合縮排要求,如 Python 網站上的《Python 程式碼格式指南》https://www.python.org/dev/peps/pep-0008/#indentation所述。如需詳細資訊,請參閱的 Python 語言支援 UDFs

SQL_clause

SQL SELECT 子句。

SELECT 子句不能包含下列任一類型的子句:

  • FROM

  • INTO

  • WHERE

  • GROUP 依 排序

  • ORDER 依 排序

  • LIMIT

LANGUAGE { plpythonu | sql }

若是 Python,指定 plpythonu。針對 SQL,指定 sql。您必須具有 SQL或 plpythonu 使用語言的許可。如需詳細資訊,請參閱UDF 安全性和許可

使用須知

巢狀函數

您可以從 內呼叫其他SQL使用者定義的函數 SQL (UDF)UDF。當您執行 CREATEFUNCTION命令時,巢狀函數必須存在。Amazon Redshift 不會追蹤 的相依性UDFs,因此如果您捨棄巢狀函數,Amazon Redshift 不會傳回錯誤。不過,如果巢狀函數不存在, UDF將會失敗。例如,下列函數會呼叫 SELECT子句中的 f_sql_greater 函數。

create function f_sql_commission (float, float ) returns float stable as $$ select f_sql_greater ($1, $2) $$ language sql;

UDF 安全性和權限

若要建立 UDF,您必須具有 SQL或 plpythonu (Python) 使用語言的許可。根據預設,USAGEON LANGUAGE SQL 會授予 PUBLIC。不過,您必須明確LANGUAGEPLPYTHONU地將 USAGE ON 授予特定使用者或群組。

若要撤銷 的使用SQL,請先撤銷 的使用PUBLIC。然後SQL僅將 上的用量授予允許建立 SQL 的特定使用者或群組UDFs。下列範例SQL會從 撤銷 上的用量,PUBLIC然後將用量授與使用者群組 udf_devs

revoke usage on language sql from PUBLIC; grant usage on language sql to group udf_devs;

若要執行 UDF,您必須具有每個函數的執行許可。根據預設, UDFs 會將新 的執行許可授予 PUBLIC。若要限制用量,請撤銷 對函數PUBLIC的執行許可。然後將許可授予特定個人或群組。

下列範例f_py_greater會從 撤銷對函數的執行許可,PUBLIC然後將用量授予使用者群組 udf_devs

revoke execute on function f_py_greater(a float, b float) from PUBLIC; grant execute on function f_py_greater(a float, b float) to group udf_devs;

根據預設,超級使用者具備所有權限。

如需詳細資訊,請參閱 GRANTREVOKE

範例

Scalar Python UDF範例

下列範例會建立 PythonUDF,比較兩個整數並傳回較大的值。

create function f_py_greater (a float, b float) returns float stable as $$ if a > b: return a return b $$ language plpythonu;

下列範例會查詢SALES資料表並呼叫新f_py_greater函數,以傳回 COMMISSION或 20% 的 PRICEPAID,以較大者為準。

select f_py_greater (commission, pricepaid*0.20) from sales;

純量SQLUDF範例

下列範例會建立一個函數,比較兩個數字並傳回較大的值。

create function f_sql_greater (float, float) returns float stable as $$ select case when $1 > $2 then $1 else $2 end $$ language sql;

下列查詢會呼叫新f_sql_greater函數來查詢SALES資料表,並傳回 COMMISSION或 20%PRICEPAID,以較大者為準。

select f_sql_greater (commission, pricepaid*0.20) from sales;