CREATE FUNCTION¶
새 UDF(사용자 정의 함수) 를 만듭니다. 이 함수는 (UDF로서) 스칼라 결과 또는 (UDTF로서) 테이블 형식 결과를 반환할 수 있습니다.
UDF를 만들 때 지원되는 언어 중 하나로 코드가 작성된 핸들러를 지정합니다. 핸들러의 언어에 따라, CREATE FUNCTION 문과 함께 인라인으로 핸들러 소스 코드를 포함하거나 핸들러가 미리 컴파일된 코드이거나 스테이지의 소스 코드인 경우 CREATE FUNCTION에서 핸들러 위치를 참조할 수 있습니다.
다음 표에는 지원되는 각 언어와 해당 코드가 CREATE FUNCTION과 함께 인라인으로 유지될 수 있는지, 또는 스테이지에 유지될 수 있는지 여부가 나열되어 있습니다. 자세한 내용은 처리기 코드를 인라인 또는 스테이지에 유지하기 섹션을 참조하십시오.
언어 |
처리기 위치 |
---|---|
인라인 또는 스테이징됨 |
|
인라인 |
|
인라인 또는 스테이징됨 |
|
인라인 또는 스테이징됨 |
|
인라인 |
구문¶
CREATE FUNCTION의 구문은 UDF 핸들러로 사용하는 언어에 따라 다릅니다.
Java 처리기¶
소스 코드가 인라인 상태인 경우 아래 구문을 사용하십시오.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE JAVA
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
[ RUNTIME_VERSION = <java_jdk_version> ]
[ COMMENT = '<string_literal>' ]
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] ) ]
[ PACKAGES = ( '<package_name_and_version>' [ , ... ] ) ]
HANDLER = '<path_to_method>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
[ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
AS '<function_definition>'
처리기 코드가 스테이지(예: JAR)에서 참조되는 경우 다음 구문을 사용합니다.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE JAVA
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
[ RUNTIME_VERSION = <java_jdk_version> ]
[ COMMENT = '<string_literal>' ]
IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
HANDLER = '<path_to_method>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
JavaScript 처리기¶
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE JAVASCRIPT
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
[ COMMENT = '<string_literal>' ]
AS '<function_definition>'
Python 처리기¶
소스 코드가 인라인 상태인 경우 아래 구문을 사용하십시오.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE PYTHON
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
RUNTIME_VERSION = <python_version>
[ COMMENT = '<string_literal>' ]
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] ) ]
[ PACKAGES = ( '<package_name>[==<version>]' [ , ... ] ) ]
HANDLER = '<function_name>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
AS '<function_definition>'
처리기 코드가 스테이지(예: 모듈)에서 참조되는 경우 다음 구문을 사용합니다.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE PYTHON
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
RUNTIME_VERSION = <python_version>
[ COMMENT = '<string_literal>' ]
IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
[ PACKAGES = ( '<package_name>[==<version>]' [ , ... ] ) ]
HANDLER = '<module_file_name>.<function_name>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
Scala 처리기¶
소스 코드가 인라인 상태인 경우 아래 구문을 사용하십시오.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS <result_data_type>
[ [ NOT ] NULL ]
LANGUAGE SCALA
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
[ RUNTIME_VERSION = <scala_version> ]
[ COMMENT = '<string_literal>' ]
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] ) ]
[ PACKAGES = ( '<package_name_and_version>' [ , ... ] ) ]
HANDLER = '<path_to_method>'
[ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
AS '<function_definition>'
처리기 코드가 스테이지(예: JAR)에서 참조되는 경우 다음 구문을 사용합니다.
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION [ IF NOT EXISTS ] <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS <result_data_type>
[ [ NOT ] NULL ]
LANGUAGE SCALA
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ]
[ RUNTIME_VERSION = <scala_version> ]
[ COMMENT = '<string_literal>' ]
IMPORTS = ( '<stage_path_and_file_name_to_read>' [ , ... ] )
HANDLER = '<path_to_method>'
SQL 처리기¶
CREATE [ OR REPLACE ] [ { TEMP | TEMPORARY } ] [ SECURE ] FUNCTION <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
[ { VOLATILE | IMMUTABLE } ]
[ MEMOIZABLE ]
[ COMMENT = '<string_literal>' ]
AS '<function_definition>'
필수 매개 변수¶
모든 언어¶
name ( [ arg_name arg_data_type [ DEFAULT default_value ] ] [ , ... ] )
UDF에 대한 식별자(
name
), 입력 인자, 선택적 인자의 기본값을 지정합니다.식별자의 경우:
UDF는 이름과 인자 타입의 조합으로 식별 및 확인 되기 때문에 식별자는 함수가 생성되는 스키마에 대해 고유할 필요가 없습니다.
식별자는 알파벳 문자로 시작해야 하며 전체 식별자 문자열을 큰따옴표(예: “My object”)로 묶지 않는 한 공백이나 특수 문자를 포함할 수 없습니다. 큰따옴표로 묶인 식별자도 대/소문자를 구분합니다. 식별자 요구 사항 섹션을 참조하십시오.
입력 인자의 경우:
arg_name
의 경우, 입력 인자의 이름을 지정합니다.arg_data_type
의 경우, 사용 중인 처리기 언어에 해당하는 Snowflake 데이터 타입을 사용합니다.Java 처리기 에 대해서는 SQL-Java 데이터 타입 매핑 섹션을 참조하십시오.
JavaScript 처리기 에 대해서는 SQL 및 JavaScript 데이터 타입 매핑 섹션을 참조하십시오.
Python 처리기 에 대해서는 SQL-Python 데이터 타입 매핑 섹션을 참조하십시오.
Scala 처리기 에 대해서는 SQL-Scala 데이터 타입 매핑 섹션을 참조하십시오.
인자가 선택 사항임을 나타내려면
DEFAULT default_value
를 사용하여 인자의 기본값을 지정하십시오. 기본값에는 리터럴이나 식을 사용할 수 있습니다.선택적 인자를 지정하는 경우 필수 인자 뒤에 배치해야 합니다.
함수에 선택적 인자가 있는 경우 이름은 동일하고 서명은 다른 추가 함수를 정의할 수 없습니다.
자세한 내용은 선택적 인자 지정하기 섹션을 참조하십시오.
RETURNS ...
UDF에서 반환하는 결과를 지정하며, 이에 따라 UDF 형식이 결정됩니다.
result_data_type
: 지정된 데이터 타입의 단일 값을 반환하는 스칼라 UDF를 만듭니다.참고
Java, Python 또는 Scala로 작성된 UDF 처리기의 경우
result_data_type
은 처리기 언어에 해당하는 다음 테이블의SQL Data Type
열에 있어야 합니다.TABLE ( col_name col_data_type , ... )
: 지정된 테이블 열과 열 형식을 포함한 테이블 형식 결과를 반환하는 테이블 UDF를 만듭니다.참고
Scala UDF의 경우 UDFs 반환 유형이 지원되지 않습니다.
AS function_definition
UDF가 호출될 때 실행되는 핸들러 코드를 정의합니다.
function_definition
값은 핸들러에 대해 지원되는 언어 중 하나로 작성된 소스 코드여야 합니다. 코드는 다음과 같을 수 있습니다.Java. 자세한 내용은 Java UDF 소개 섹션을 참조하십시오.
JavaScript. 자세한 내용은 JavaScript UDF 소개 섹션을 참조하십시오.
Python. 자세한 내용은 Python UDF 소개 섹션을 참조하십시오.
Scala 자세한 내용은 Scala UDF 소개 섹션을 참조하십시오.
SQL 식입니다. 자세한 내용은 SQL UDF 소개 섹션을 참조하십시오.
자세한 내용은 이 항목에 있는 사용법 노트 섹션을 참조하십시오.
참고
IMPORTS 절이 있는 스테이지에서 UDF 핸들러 코드를 참조할 때 AS 절이 필요하지 않습니다.
Java¶
LANGUAGE JAVA
코드가 Java 언어로 되어 있음을 지정합니다.
RUNTIME_VERSION = java_jdk_version
사용할 Java JDK 런타임 버전을 지정합니다. 지원되는 Java 버전은 다음과 같습니다.
11.x
17.x(이 함수에 대한 미리 보기 지원은 모든 계정에서 사용할 수 있습니다.)
RUNTIME_VERSION 이 설정되어 있지 않으면 Java JDK 11이 사용됩니다.
IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )
가져올 파일의 위치(스테이지), 경로, 이름입니다.
파일은 JAR 파일 또는 다른 유형의 파일일 수 있습니다.
파일이 JAR 파일인 경우 하나 이상의 .class 파일과 0개 또는 그 이상의 리소스 파일을 포함할 수 있습니다.
JNI(Java 네이티브 인터페이스)는 지원되지 않습니다. Snowflake는 (Java 바이트 코드와는 대조적으로) 네이티브 코드가 포함된 라이브러리를 로딩하는 것을 금지합니다.
Java UDFs는 JAR 파일이 아닌 파일도 읽을 수 있습니다. 예를 보려면 IMPORTS에서 정적으로 지정된 파일 읽기 를 참조하십시오.
파일(JAR 파일 또는 기타 파일)을 스테이지로 복사하려는 경우 Snowflake에서는 명명된 내부 스테이지 사용을 권장합니다. 이는 PUT 명령이 명명된 내부 스테이지로의 파일 복사를 지원하고 PUT 명령이 보통은 JAR 파일을 스테이지로 가장 쉽게 이동하는 방법이기 때문입니다.
외부 스테이지가 허용되지만, PUT 의 지원을 받지 않습니다.
파일이 다른 하위 디렉터리나 다른 스테이지에 있더라도 IMPORTS 절의 각 파일은 고유한 이름을 가져야 합니다.
IMPORTS 및 TARGET_PATH 절이 모두 있는 경우, 파일이 다른 하위 디렉터리나 다른 스테이지에 있더라도 TARGET_PATH 절의 파일 이름은 IMPORTS 절의 각 파일 이름과 달라야 합니다.
Snowflake에서는 TARGET_PATH 가 기존 파일과 일치하는 경우 오류를 반환합니다. TARGET_PATH 를 사용해 기존 파일을 덮어쓸 수 없습니다.
처리기가 스테이지에 있는 UDF의 경우 UDF를 포함한 JAR 파일의 위치를 지정해주는 IMPORTS 절이 필요합니다.
처리기 코드가 인라인 상태인 UDF의 경우, 인라인 UDF가 라이브러리 또는 텍스트 파일과 같은 다른 파일에 액세스해야 할 때만 IMPORTS 절이 필요합니다.
Snowpark 패키지 와 같은 Snowflake 시스템 패키지의 경우 JAR 파일을 IMPORTS 로 지정하는 대신 PACKAGES 절로 패키지를 지정할 수 있습니다. 이때 패키지 JAR 파일을 IMPORTS 값에 포함할 필요는 없습니다.
인라인 Java
AS function_definition
인라인 Java UDFs는 함수 정의 가 필수적입니다.
HANDLER = handler_name
처리기 메서드 또는 클래스의 이름입니다.
처리기가 테이블 형식이 아닌 값을 반환하는 스칼라 UDF의 처리기인 경우 HANDLER 값은
MyClass.myMethod
형식에서처럼 메서드 이름이어야 합니다.핸들러가 테이블 형식의 UDF인 경우 HANDLER 값은 핸들러 클래스의 이름이어야 합니다.
JavaScript¶
LANGUAGE JAVASCRIPT
코드가 JavaScript 언어로 되어 있음을 지정합니다.
Python¶
LANGUAGE PYTHON
코드가 Python 언어로 되어 있음을 지정합니다.
RUNTIME_VERSION = python_version
사용할 Python 버전을 지정합니다. 지원되는 Python 버전은 다음과 같습니다.
3.8
3.9
3.10
3.11
IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )
가져올 파일의 위치(스테이지), 경로, 이름입니다.
파일은
.py
파일 또는 다른 유형의 파일일 수 있습니다.Python UDF는 텍스트 파일과 같은 Python 파일 이외의 파일도 읽을 수 있습니다. 예를 보려면 파일 읽기 를 참조하십시오.
파일을 스테이지로 복사하려는 경우 Snowflake에서는 명명된 내부 스테이지 사용을 권장합니다. 이는 PUT 명령이 명명된 내부 스테이지로의 파일 복사를 지원하고 PUT 명령이 보통은 파일을 스테이지로 가장 쉽게 이동하는 방법이기 때문입니다.
외부 스테이지가 허용되지만, PUT 의 지원을 받지 않습니다.
파일이 다른 하위 디렉터리나 다른 스테이지에 있더라도 IMPORTS 절의 각 파일은 고유한 이름을 가져야 합니다.
핸들러 코드가 스테이지에 저장되어 있으면 IMPORTS 절을 사용하여 핸들러 코드의 위치를 지정해야 합니다.
인라인 Python UDF의 경우, UDF 핸들러가 패키지 또는 텍스트 파일과 같은 다른 파일에 액세스해야 할 때만 IMPORTS 절이 필요합니다.
numpy 과 같은 Snowflake 시스템에 포함된 패키지의 경우, PACKAGES 절만 사용해 패키지를 지정하여 패키지 원본을 IMPORTS 값으로 생략할 수 있습니다.
HANDLER = handler_name
처리기 함수 또는 클래스의 이름입니다.
핸들러가 스칼라 UDF용으로, 테이블 형식이 아닌 값을 반환하는 경우, HANDLER 값은 함수 이름이어야 합니다. 핸들러 코드가 CREATE FUNCTION 문과 인라인일 경우 함수 이름만 사용할 수 있습니다. 핸들러 코드가 스테이지에서 참조될 때 이 값은
my_module.my_function
형식에서처럼 모듈 이름으로 정규화되어야 합니다.핸들러가 테이블 형식의 UDF인 경우 HANDLER 값은 핸들러 클래스의 이름이어야 합니다.
Scala¶
LANGUAGE SCALA
코드가 Scala 언어로 되어 있음을 지정합니다.
RUNTIME_VERSION = scala_version
사용할 Scala 런타임 버전을 지정합니다. 지원되는 Scala 버전은 다음과 같습니다.
2.12
RUNTIME_VERSION 이 설정되지 않은 경우 Scala 2.12가 사용됩니다.
IMPORTS = ( 'stage_path_and_file_name_to_read' [ , ... ] )
JAR 또는 다른 종류의 파일과 같이, 가져올 파일의 위치(스테이지), 경로, 이름입니다.
JAR 파일에는 처리기 종속성 라이브러리가 포함될 수 있습니다. 하나 이상의 .class 파일과 0개 또는 그 이상의 리소스 파일을 포함할 수 있습니다.
JNI(Java 네이티브 인터페이스)는 지원되지 않습니다. Snowflake는 (Java 바이트 코드와는 대조적으로) 네이티브 코드가 포함된 라이브러리를 로딩하는 것을 금지합니다.
JAR 파일이 아닌 파일은 처리기 코드에서 읽은 파일일 수 있습니다. 예를 보려면 IMPORTS에서 정적으로 지정된 파일 읽기 를 참조하십시오.
파일을 스테이지로 복사하려는 경우 Snowflake에서는 명명된 내부 스테이지 사용을 권장합니다. 이는 PUT 명령이 명명된 내부 스테이지로의 파일 복사를 지원하고 PUT 명령이 보통은 JAR 파일을 스테이지로 가장 쉽게 이동하는 방법이기 때문입니다. 외부 스테이지가 허용되지만, PUT 의 지원을 받지 않습니다.
파일이 다른 스테이지 하위 디렉터리나 다른 스테이지에 있더라도 IMPORTS 절의 각 파일은 고유한 이름을 가져야 합니다.
IMPORTS 및 TARGET_PATH 절이 모두 있는 경우, 파일이 다른 스테이지 하위 디렉터리나 다른 스테이지에 있더라도 TARGET_PATH 절의 파일 이름은 IMPORTS 절에 나열된 파일의 이름과 달라야 합니다.
처리기가 스테이지에 있는 UDF의 경우 UDF를 포함한 JAR 파일의 위치를 지정해주는 IMPORTS 절이 필요합니다.
처리기 코드가 인라인 상태인 UDF의 경우, 인라인 UDF가 라이브러리 또는 텍스트 파일과 같은 다른 파일에 액세스해야 할 때만 IMPORTS 절이 필요합니다.
Snowpark 패키지 와 같은 Snowflake 시스템 패키지의 경우 JAR 파일을 IMPORTS 로 지정하는 대신 PACKAGES 절로 패키지를 지정할 수 있습니다. 이때 패키지 JAR 파일을 IMPORTS 값에 포함할 필요는 없습니다.
인라인 Scala
AS function_definition
인라인 Scala 처리기 코드가 있는 UDF에는 함수 정의 가 필요합니다.
HANDLER = handler_name
처리기 메서드 또는 클래스의 이름입니다.
처리기가 테이블 형식이 아닌 값을 반환하는 스칼라 UDF의 처리기인 경우 HANDLER 값은
MyClass.myMethod
형식에서처럼 메서드 이름이어야 합니다.
선택적 매개 변수¶
모든 언어¶
SECURE
함수가 안전한 것으로 지정합니다. 보안 함수에 대한 자세한 내용은 Secure UDF와 저장 프로시저로 민감한 정보 보호하기 를 참조하십시오.
{ TEMP | TEMPORARY }
함수가 해당 함수를 생성한 세션 의 지속 기간 동안만 지속되도록 지정합니다. 임시 함수는 세션이 끝나면 삭제됩니다.
기본값: 값 없음.
TEMPORARY
로 선언되지 않은 함수는 영구적입니다.스키마에 이미 존재하는 함수와 이름이 같은 임시 사용자 정의 함수 를 생성할 수 없습니다.
[ [ NOT ] NULL ]
함수가 NULL 값을 반환할 수 있거나 NON-NULL 값만 반환해야 할지 여부를 지정합니다. 기본값은 NULL입니다(즉, 이 함수는 NULL을 반환할 수 있음).
참고
현재,
NOT NULL
절은 SQL UDFs에 대해 적용되지 않습니다.NOT NULL
로 선언된 SQL UDFs는 NULL 값을 반환할 수 있습니다. Snowflake는 NULL 값이 절대 반환되지 않도록 함수의 코드를 작성하지 않은 경우 SQL UDFs에 대해NOT NULL
을 피할 것을 권장합니다.
CALLED ON NULL INPUT
또는 .{ RETURNS NULL ON NULL INPUT | STRICT }
null 입력으로 호출 시 UDF의 동작을 지정합니다. 입력값이 null일 때 항상 null을 반환하는 시스템 정의 함수와는 반대로, UDFs는 null 입력을 처리하여 입력값이 null일 때도 null이 아닌 값을 반환할 수 있습니다.
CALLED ON NULL INPUT
은 항상 null 입력으로 UDF를 호출합니다. 그와 같은 값을 적절히 처리하는 것은 UDF에 달려 있습니다.입력값이 null인 경우
RETURNS NULL ON NULL INPUT
(또는 그 동의어인STRICT
)은 UDF를 호출하지 않습니다. 대신, 해당 행에 대해 항상 null 값이 반환됩니다. UDF는 null이 아닌 입력값에 대해 여전히 null을 반환할 수도 있습니다.
참고
SQL UDF에 대해
RETURNS NULL ON NULL INPUT
(STRICT
)이 지원되지 않습니다. SQL UDF는 사실상CALLED ON NULL INPUT
을 사용합니다. SQL UDF에서 null 입력값을 처리해야 합니다.기본값:
CALLED ON NULL INPUT
{ VOLATILE | IMMUTABLE }
결과를 반환할 때 UDF의 동작을 지정합니다.
VOLATILE
: (예: 비결정성 및 상태 저장으로 인해) UDF는 똑같은 입력에 대해서도 다른 행에 대해 다른 값을 반환할 수 있습니다.IMMUTABLE
: UDF는 같은 입력으로 호출 시 함수가 항상 같은 결과를 반환한다고 가정합니다. 이 보증은 확인되지 않습니다. 같은 입력에 대해 다른 값을 반환하는 UDF에 대해IMMUTABLE
을 지정하면 정의되지 않은 동작이 이루어집니다.
기본값:
VOLATILE
COMMENT = 'string_literal'
SHOW FUNCTIONS 및 SHOW USER FUNCTIONS 출력의 DESCRIPTION 열에 표시되는 UDF에 대한 설명을 지정합니다.
기본값:
user-defined function
COPY GRANTS
CREATE OR REPLACE FUNCTION을 사용하여 새 함수를 만들 때 원래 함수의 액세스 권한을 유지하도록 지정합니다.
이 매개 변수는 OWNERSHIP을 제외한 모든 권한을 기존 함수에서 새 함수로 복사합니다. 새 함수는 스키마의 오브젝트 유형에 대해 정의된 향후 모든 권한 부여를 상속합니다. 기본적으로, CREATE FUNCTION 문을 실행하는 역할은 새 함수를 소유합니다.
참고:
데이터 공유 사용 시, 기존 함수가 다른 계정에 공유된 경우 대체 함수도 공유됩니다.
대체 함수에 대한 SHOW GRANTS 출력에는 CREATE FUNCTION 문이 실행될 때 현재 타임스탬프를 포함한 이 문을 실행한 역할로서 복사된 권한의 피부여자가 나열됩니다.
권한 부여 복사 작업은 CREATE FUNCTION 명령에서 원자적으로(즉, 같은 트랜잭션 내에서) 발생합니다.
Java¶
PACKAGES = ( 'package_name_and_version' [ , ... ] )
종속 항목으로 필요한 Snowflake 시스템 패키지의 이름 및 버전 번호. 값은
package_name:version_number
형식이어야 하며, 여기서package_name
은snowflake_domain:package
입니다. Snowflake가 시스템에서 제공되는 최신 버전을 사용하도록 하려면latest
를 버전 번호로 지정할 수 있습니다.예:
-- Use version 1.2.0 of the Snowpark package. PACKAGES=('com.snowflake:snowpark:1.2.0') -- Use the latest version of the Snowpark package. PACKAGES=('com.snowflake:snowpark:latest')
Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'java';
PACKAGES 로 지정하는 종속성의 경우 IMPORTS 절에 JAR 파일도 지정할 필요는 없습니다.
인라인 Java
TARGET_PATH = stage_path_and_file_name_to_write
TARGET_PATH 절은
function_definition
에 지정된 소스 코드를 컴파일한 후 Snowflake가 컴파일된 코드(JAR 파일)를 작성해야 하는 위치를 지정합니다.이 절이 포함된 경우 JAR 파일이 더 이상 필요하지 않을 때(일반적으로 Java UDF 삭제 시) 사용자는 이 파일을 수동으로 제거해야 합니다.
이 절을 생략할 경우 Snowflake는 코드가 필요할 때마다 소스 코드를 다시 컴파일합니다. JAR 파일은 영구적으로 저장되지 않으며 사용자가 JAR 파일을 정리할 필요는 없습니다.
Snowflake에서는 TARGET_PATH 가 기존 파일과 일치하는 경우 오류를 반환합니다. TARGET_PATH 를 사용해 기존 파일을 덮어쓸 수 없습니다.
EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )
이 함수의 처리기 코드가 외부 네트워크에 액세스하려면 필요한 외부 액세스 통합 의 이름입니다.
외부 액세스 통합에는 처리기 코드가 외부 네트워크(예: 외부REST API)를 요청하는 데 필요한 외부 위치와 자격 증명(있는 경우)을 지정하는 네트워크 규칙 및 시크릿 이 포함됩니다.
자세한 내용은 외부 네트워크 액세스 개요 섹션을 참조하십시오.
SECRETS = ( 'secret_variable_name' = secret_name [ , ... ] )
처리기 코드의 시크릿에서 정보를 검색할 때 변수를 사용하여 시크릿을 참조할 수 있도록 시크릿 이름을 변수에 할당합니다.
이 매개 변수의 값은 다음 부분을 포함한 할당 식의 쉼표로 구분된 목록입니다.
외부 액세스 통합의 ALLOWED_AUTHENTICATION_SECRETS 매개 변수 값에 지정된 시크릿의 이름인
secret_name
. 결국, 해당 외부 액세스 통합의 이름은 이 CREATE FUNCTION 호출의 EXTERNAL_ACCESS_INTEGRATIONS 매개 변수 값으로 지정해야 합니다.EXTERNAL_ACCESS_INTEGRATIONS 매개 변수로 지정된 통합에도 시크릿이 포함되지 않은 SECRETS 값을 지정하면 오류가 발생합니다.
시크릿에서 정보를 검색할 때 처리기 코드에서 사용할 변수인
'secret_variable_name'
.
예를 포함한 자세한 내용은 함수 또는 프로시저에서 외부 액세스 통합 사용하기 섹션을 참조하십시오.
Python¶
PACKAGES = ( 'package_name_and_version' [ , ... ] )
종속 항목으로 필요한 패키지의 이름 및 버전 번호. 값은
package_name==version_number
형식이어야 합니다. 버전 번호를 생략할 경우 Snowflake는 시스템에서 사용 가능한 최신 패키지를 사용합니다.예:
-- Use version 1.2.2 of the NumPy package. PACKAGES=('numpy==1.2.2') -- Use the latest version of the NumPy package. PACKAGES=('numpy')
Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'python';
포함된 패키지에 대한 자세한 내용은 서드 파티 패키지 사용하기 섹션을 참조하십시오.
EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )
이 함수의 처리기 코드가 외부 네트워크에 액세스하려면 필요한 외부 액세스 통합 의 이름입니다.
외부 액세스 통합에는 처리기 코드가 외부 네트워크(예: 외부REST API)를 요청하는 데 필요한 외부 위치와 자격 증명(있는 경우)을 지정하는 네트워크 규칙 및 시크릿 이 포함됩니다.
자세한 내용은 외부 네트워크 액세스 개요 섹션을 참조하십시오.
SECRETS = ( 'secret_variable_name' = secret_name [ , ... ])
처리기 코드의 시크릿에서 정보를 검색할 때 변수를 사용하여 시크릿을 참조할 수 있도록 시크릿 이름을 변수에 할당합니다.
이 매개 변수의 값은 다음 부분을 포함한 할당 식의 쉼표로 구분된 목록입니다.
외부 액세스 통합의 ALLOWED_AUTHENTICATION_SECRETS 매개 변수 값에 지정된 시크릿의 이름인
secret_name
. 결국, 해당 외부 액세스 통합의 이름은 이 CREATE FUNCTION 호출의 EXTERNAL_ACCESS_INTEGRATIONS 매개 변수 값으로 지정해야 합니다.EXTERNAL_ACCESS_INTEGRATIONS 매개 변수로 지정된 통합에도 시크릿이 포함되지 않은 SECRETS 값을 지정하면 오류가 발생합니다.
시크릿에서 정보를 검색할 때 처리기 코드에서 사용할 변수인
'secret_variable_name'
.
예를 포함한 자세한 내용은 함수 또는 프로시저에서 외부 액세스 통합 사용하기 섹션을 참조하십시오.
SQL¶
MEMOIZABLE
함수가 메모이제이션 가능한 것으로 지정합니다.
자세한 내용은 메모이제이션 가능 UDF 섹션을 참조하십시오.
Scala¶
PACKAGES = ( 'package_name_and_version' [ , ... ] )
종속 항목으로 필요한 Snowflake 시스템 패키지의 이름 및 버전 번호. 값은
package_name:version_number
형식이어야 하며, 여기서package_name
은snowflake_domain:package
입니다. Snowflake가 시스템에서 제공되는 최신 버전을 사용하도록 하려면latest
를 버전 번호로 지정할 수 있습니다.예:
-- Use version 1.7.0 of the Snowpark package. PACKAGES=('com.snowflake:snowpark:1.7.0') -- Use the latest version of the Snowpark package. PACKAGES=('com.snowflake:snowpark:latest')
Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'scala';
PACKAGES 로 지정하는 종속성의 경우 IMPORTS 절에 JAR 파일도 지정할 필요는 없습니다.
인라인 Scala
TARGET_PATH = stage_path_and_file_name_to_write
TARGET_PATH 절은
function_definition
에 지정된 소스 코드를 컴파일한 후 Snowflake가 컴파일된 코드(JAR 파일)를 작성해야 하는 위치를 지정합니다.이 절이 포함된 경우 JAR 파일이 더 이상 필요하지 않을 때(일반적으로 UDF 삭제 시) 이 파일을 수동으로 제거해야 합니다.
이 절을 생략할 경우 Snowflake는 코드가 필요할 때마다 소스 코드를 다시 컴파일합니다. JAR 파일은 영구적으로 저장되지 않으며 JAR 파일을 정리할 필요는 없습니다.
Snowflake에서는 TARGET_PATH 가 기존 파일과 일치하는 경우 오류를 반환합니다. TARGET_PATH 를 사용해 기존 파일을 덮어쓸 수 없습니다.
액세스 제어 요구 사항¶
이 SQL 명령을 실행하는 데 사용되는 역할 에는 최소한 다음 권한 이 있어야 합니다.
권한 |
오브젝트 |
참고 |
---|---|---|
CREATE FUNCTION |
스키마 |
|
USAGE |
함수 |
새로 생성된 함수에 대한 USAGE 권한을 역할에 부여하면 그 역할을 가진 사용자가 Snowflake의 다른 곳에서 함수를 호출할 수 있습니다(예: 외부 토큰화를 위한 마스킹 정책 소유자 역할). |
USAGE |
외부 액세스 통합 |
통합(있는 경우)에 필요하며, EXTERNAL_ACCESS_INTEGRATIONS 매개 변수로 지정됩니다. 자세한 내용은 CREATE EXTERNAL ACCESS INTEGRATION 섹션을 참조하십시오. |
READ |
시크릿 |
SECRETS 매개 변수로 지정된 시크릿(있는 경우)에 필요합니다. 자세한 내용은 자격 증명을 나타내는 시크릿 만들기 및 함수 또는 프로시저에서 외부 액세스 통합 사용하기 섹션을 참조하십시오. |
USAGE |
스키마 |
SECRETS 매개 변수로 지정된 시크릿이 포함된 스키마(있는 경우)에 필요합니다. 자세한 내용은 자격 증명을 나타내는 시크릿 만들기 및 함수 또는 프로시저에서 외부 액세스 통합 사용하기 섹션을 참조하십시오. |
스키마의 모든 오브젝트에 대해 작업하려면 상위 데이터베이스 및 스키마에 대한 USAGE 권한도 필요합니다.
지정된 권한 세트로 사용자 지정 역할을 만드는 방법에 대한 지침은 사용자 지정 역할 만들기 섹션을 참조하십시오.
보안 오브젝트 에 대해 SQL 작업을 수행하기 위한 역할과 권한 부여에 대한 일반적인 정보는 액세스 제어의 개요 섹션을 참조하십시오.
사용법 노트¶
모든 언어¶
function_definition
에는 크기 제한이 있습니다. 허용 가능한 최대 크기는 변경될 수 있습니다.function_definition
주위의 구분 기호는 작은따옴표 또는 한 쌍의 달러 기호일 수 있습니다.$$
를 구분 기호로 사용하면 작은따옴표가 포함된 함수를 더 쉽게 작성할 수 있습니다.함수 본문의 구분 기호가 작은따옴표 문자인 경우
function_definition
내의 모든 작은따옴표(예: 문자열 리터럴)를 작은따옴표로 이스케이프해야 합니다.마스킹 정책 에서 UDF를 사용하는 경우 열의 데이터 타입, UDF, 마스킹 정책이 일치하는지 확인하십시오. 자세한 내용은 마스킹 정책의 사용자 정의 함수 섹션을 참조하십시오.
메타데이터 관련:
주의
고객은 Snowflake 서비스를 사용할 때 개인 데이터(사용자 오브젝트 제외), 민감한 데이터, 수출 통제 대상 데이터 또는 기타 규제 데이터가 메타데이터로 입력되지 않도록 해야 합니다. 자세한 내용은 Snowflake의 메타데이터 필드 섹션을 참조하십시오.
CREATE OR REPLACE <오브젝트> 문은 원자성입니다. 즉, 오브젝트가 바뀔 때 단일 트랜잭션으로 이전 오브젝트가 삭제되고 새 오브젝트가 생성됩니다.
Java¶
Java에서 기본 데이터 타입은 NULL 값을 허용하지 않으므로, 이러한 유형의 인자에 대해 NULL을 전달하면 오류가 발생합니다.
HANDLER 절에서 메서드 이름은 대/소문자를 구분합니다.
IMPORTS 및 TARGET_PATH 절에서는 다음과 같습니다.
패키지, 클래스 및 파일 이름은 대/소문자를 구분합니다.
스테이지 이름은 대/소문자를 구분하지 않습니다.
PACKAGES 절을 사용하여 Snowpark의 종속 항목과 같이, Snowflake 시스템 정의 종속 항목의 패키지 이름과 버전 번호를 지정할 수 있습니다. 다른 종속 항목의 경우 IMPORTS 절을 사용하여 종속 항목 JAR 파일을 지정합니다.
Snowflake는 다음의 유효성을 검사합니다.
CREATE FUNCTION 문의 HANDLER에 지정된 JAR 파일이 존재하고 이 파일에는 지정된 클래스와 메서드가 있습니다.
UDF 선언에 지정된 입력 및 출력 유형은 Java 메서드의 입력 및 출력 유형과 호환됩니다.
유효성 검사는 생성 시 또는 실행 시에 수행될 수 있습니다.
CREATE FUNCTION 문이 실행될 때 사용자가 활성 Snowflake 웨어하우스에 연결되어 있으면 생성 시에 UDF의 유효성이 검사됩니다.
그렇지 않으면, UDF가 생성되지만 유효성 검사가 즉시 이루어지지 않으며 Snowflake는
Function <이름> created successfully, but could not be validated since there is no active warehouse
메시지를 반환합니다.
JavaScript¶
Snowflake는 UDF 생성 시간에 JavaScript 코드의 유효성을 검사하지 않습니다(즉, 코드가 유효한지 여부와 관계없이 UDF 생성에 성공함). 코드가 유효하지 않으면 쿼리 시간에 UDF가 호출될 때 오류가 반환됩니다.
Python¶
HANDLER 절에서 핸들러 함수 이름은 대/소문자를 구분합니다.
IMPORTS 절에서:
파일 이름은 대/소문자를 구분합니다.
스테이지 이름은 대/소문자를 구분하지 않습니다.
PACKAGES 절을 사용하여 Snowpark의 종속 항목과 같이, 종속 항목의 패키지 이름과 버전 번호를 지정할 수 있습니다. 다른 종속 항목의 경우 IMPORTS 절을 사용하여 종속 항목 파일을 지정합니다.
Snowflake는 다음의 유효성을 검사합니다.
CREATE FUNCTION 문의 HANDLER에 지정된 함수 또는 클래스가 존재합니다.
UDF 선언에 지정된 입력 및 출력 유형은 핸들러의 입력 및 출력 유형과 호환됩니다.
Scala¶
HANDLER 절에서 메서드 이름은 대/소문자를 구분합니다.
IMPORTS 및 TARGET_PATH 절에서는 다음과 같습니다.
패키지, 클래스 및 파일 이름은 대/소문자를 구분합니다.
스테이지 이름은 대/소문자를 구분하지 않습니다.
PACKAGES 절을 사용하여 Snowpark의 종속 항목과 같이, Snowflake 시스템 정의 종속 항목의 패키지 이름과 버전 번호를 지정할 수 있습니다. 다른 종속 항목의 경우 IMPORTS 절을 사용하여 종속 항목 JAR 파일을 지정합니다.
Snowflake는 다음의 유효성을 검사합니다.
CREATE FUNCTION 문의 HANDLER에 지정된 JAR 파일이 존재하고 이 파일에는 지정된 클래스와 메서드가 있습니다.
UDF 선언에 지정된 입력 및 출력 유형은 Scala 메서드의 입력 및 출력 유형과 호환됩니다.
유효성 검사는 생성 시 또는 실행 시에 수행될 수 있습니다.
CREATE FUNCTION 문이 실행될 때 사용자가 활성 Snowflake 웨어하우스에 연결되어 있으면 생성 시에 UDF의 유효성이 검사됩니다.
그렇지 않으면, UDF가 생성되지만 유효성 검사가 즉시 이루어지지 않으며 Snowflake는
Function <이름> created successfully, but could not be validated since there is no active warehouse
메시지를 반환합니다.
SQL¶
현재, NOT NULL 절은 SQL UDF에 대해 적용되지 않습니다.
예¶
Java¶
다음은 인라인 처리기가 있는 CREATE FUNCTION의 기본적인 예입니다.
create or replace function echo_varchar(x varchar)
returns varchar
language java
called on null input
handler='TestFunc.echoVarchar'
target_path='@~/testfunc.jar'
as
'class TestFunc {
public static String echoVarchar(String x) {
return x;
}
}';
다음은 스테이징된 처리기에 대한 참조가 있는 CREATE FUNCTION의 기본적인 예입니다.
create function my_decrement_udf(i numeric(9, 0))
returns numeric
language java
imports = ('@~/my_decrement_udf_package_dir/my_decrement_udf_jar.jar')
handler = 'my_decrement_udf_package.my_decrement_udf_class.my_decrement_udf_method'
;
Java UDFs의 더 많은 예는 예 를 참조하십시오.
JavaScript¶
js_factorial
로 명명된 JavaScript UDF 만들기:
CREATE OR REPLACE FUNCTION js_factorial(d double)
RETURNS double
LANGUAGE JAVASCRIPT
STRICT
AS '
if (D <= 0) {
return 1;
} else {
var result = 1;
for (var i = 2; i <= D; i++) {
result = result * i;
}
return result;
}
';
Python¶
다음 예제의 코드는 핸들러 코드가 udf
로 인라인인 py_udf
함수를 만듭니다.
CREATE OR REPLACE FUNCTION py_udf()
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('numpy','pandas','xgboost==1.5.0')
HANDLER = 'udf'
AS $$
import numpy as np
import pandas as pd
import xgboost as xgb
def udf():
return [np.__version__, pd.__version__, xgb.__version__]
$$;
다음 예제의 코드는 @my_stage
스테이지에 있는 sleepy.py
파일에 핸들러가 있는 dream
함수를 만듭니다.
CREATE OR REPLACE FUNCTION dream(i int)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'sleepy.snore'
IMPORTS = ('@my_stage/sleepy.py')
Scala¶
다음은 인라인 처리기가 있는 CREATE FUNCTION의 기본적인 예입니다.
CREATE OR REPLACE FUNCTION echo_varchar(x VARCHAR)
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = 2.12
HANDLER='Echo.echoVarchar'
AS
$$
class Echo {
def echoVarchar(x : String): String = {
return x
}
}
$$;
다음은 스테이징된 처리기에 대한 참조가 있는 CREATE FUNCTION의 기본적인 예입니다.
CREATE OR REPLACE FUNCTION echo_varchar(x VARCHAR)
RETURNS VARCHAR
LANGUAGE SCALA
RUNTIME_VERSION = 2.12
IMPORTS = ('@udf_libs/echohandler.jar')
HANDLER='Echo.echoVarchar';
Scala UDF의 더 많은 예는 Scala UDF 처리기의 예 섹션을 참조하십시오.
SQL¶
수학 상수 pi의 하드 코드된 근사값을 반환하는 간단한 SQL 스칼라 UDF 만들기:
CREATE FUNCTION pi_udf()
RETURNS FLOAT
AS '3.141592654::FLOAT'
;
하드 코드된 값을 반환하는 간단한 SQL 테이블 UDF 만들기:
CREATE FUNCTION simple_table_function ()
RETURNS TABLE (x INTEGER, y INTEGER)
AS
$$
SELECT 1, 2
UNION ALL
SELECT 3, 4
$$
;
SELECT * FROM TABLE(simple_table_function());
출력:
SELECT * FROM TABLE(simple_table_function());
+---+---+
| X | Y |
|---+---|
| 1 | 2 |
| 3 | 4 |
+---+---+
여러 매개 변수를 허용하는 UDF 만들기:
CREATE FUNCTION multiply1 (a number, b number)
RETURNS number
COMMENT='multiply two numbers'
AS 'a * b';
쿼리의 결과를 반환하고 get_countries_for_user
로 명명된 SQL 테이블 UDF 만들기:
CREATE OR REPLACE FUNCTION get_countries_for_user ( id NUMBER )
RETURNS TABLE (country_code CHAR, country_name VARCHAR)
AS 'SELECT DISTINCT c.country_code, c.country_name
FROM user_addresses a, countries c
WHERE a.user_id = id
AND c.country_code = a.country_code';