本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
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;
根據預設,超級使用者具備所有權限。
範例
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;