CREATE FUNCTION

UDF(사용자 정의 함수) 를 만듭니다. 이 함수는 (UDF로서) 스칼라 결과 또는 (UDTF로서) 테이블 형식 결과를 반환할 수 있습니다.

UDF를 만들 때 지원되는 언어 중 하나로 코드가 작성된 핸들러를 지정합니다. 핸들러의 언어에 따라, CREATE FUNCTION 문과 함께 인라인으로 핸들러 소스 코드를 포함하거나 핸들러가 미리 컴파일된 코드이거나 스테이지의 소스 코드인 경우 CREATE FUNCTION에서 핸들러 위치를 참조할 수 있습니다.

다음 표에는 지원되는 각 언어와 해당 코드가 CREATE FUNCTION과 함께 인라인으로 유지될 수 있는지, 또는 스테이지에 유지될 수 있는지 여부가 나열되어 있습니다. 자세한 내용은 처리기 코드를 인라인 또는 스테이지에 유지하기 섹션을 참조하십시오.

언어

처리기 위치

Java

인라인 또는 스테이징됨

JavaScript

인라인

Python

인라인 또는 스테이징됨

Scala

인라인 또는 스테이징됨

SQL

인라인

참고 항목:

ALTER FUNCTION, DROP FUNCTION, SHOW USER FUNCTIONS , DESCRIBE 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>'
Copy

처리기 코드가 스테이지(예: 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> [ , ... ] ) ]
Copy

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>'
Copy

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>'
Copy

처리기 코드가 스테이지(예: 모듈)에서 참조되는 경우 다음 구문을 사용합니다.

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> [ , ... ] ) ]
Copy

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>'
Copy

처리기 코드가 스테이지(예: 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>'
Copy

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>'
Copy

필수 매개 변수

모든 언어

name ( [ arg_name arg_data_type [ DEFAULT default_value ] ] [ , ... ] )

UDF에 대한 식별자(name), 입력 인자, 선택적 인자의 기본값을 지정합니다.

  • 식별자의 경우:

    • UDF는 이름과 인자 타입의 조합으로 식별 및 확인 되기 때문에 식별자는 함수가 생성되는 스키마에 대해 고유할 필요가 없습니다.

    • 식별자는 알파벳 문자로 시작해야 하며 전체 식별자 문자열을 큰따옴표(예: 《My object》)로 묶지 않는 한 공백이나 특수 문자를 포함할 수 없습니다. 큰따옴표로 묶인 식별자도 대/소문자를 구분합니다. 식별자 요구 사항 섹션을 참조하십시오.

  • 입력 인자의 경우:

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 값은 핸들러에 대해 지원되는 언어 중 하나로 작성된 소스 코드여야 합니다. 코드는 다음과 같을 수 있습니다.

자세한 내용은 이 항목에 있는 사용법 노트 섹션을 참조하십시오.

참고

IMPORTS 절이 있는 스테이지에서 UDF 핸들러 코드를 참조할 때 AS 절이 필요하지 않습니다.

Java

LANGUAGE JAVA

코드가 Java 언어로 되어 있음을 지정합니다.

RUNTIME_VERSION = java_jdk_version

사용할 Java JDK 런타임 버전을 지정합니다. 지원되는 Java 버전은 다음과 같습니다.

  • 11.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

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 FUNCTIONSSHOW 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_namesnowflake_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')
Copy

Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'java';
Copy

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')
Copy

Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'python';
Copy

포함된 패키지에 대한 자세한 내용은 서드 파티 패키지 사용하기 섹션을 참조하십시오.

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_namesnowflake_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')
Copy

Snowflake에서 다음 SQL을 실행하여 지원되는 시스템 패키지 목록을 검색할 수 있습니다.

SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'scala';
Copy

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 섹션을 참조하십시오.

스키마의 모든 오브젝트에 대해 작업하려면 상위 데이터베이스 및 스키마에 대한 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;
  }
}';
Copy

다음은 스테이징된 처리기에 대한 참조가 있는 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'
    ;
Copy

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;
  }
  ';
Copy

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__]
$$;
Copy

다음 예제의 코드는 @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')
Copy

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
    }
  }
  $$;
Copy

다음은 스테이징된 처리기에 대한 참조가 있는 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';
Copy

Scala UDF의 더 많은 예는 Scala UDF 처리기의 예 섹션을 참조하십시오.

SQL

수학 상수 pi의 하드 코드된 근사값을 반환하는 간단한 SQL 스칼라 UDF 만들기:

CREATE FUNCTION pi_udf()
  RETURNS FLOAT
  AS '3.141592654::FLOAT'
  ;
Copy

하드 코드된 값을 반환하는 간단한 SQL 테이블 UDF 만들기:

CREATE FUNCTION simple_table_function ()
  RETURNS TABLE (x INTEGER, y INTEGER)
  AS
  $$
    SELECT 1, 2
    UNION ALL
    SELECT 3, 4
  $$
  ;
Copy
SELECT * FROM TABLE(simple_table_function());
Copy

출력:

SELECT * FROM TABLE(simple_table_function());
+---+---+
| X | Y |
|---+---|
| 1 | 2 |
| 3 | 4 |
+---+---+
Copy

여러 매개 변수를 허용하는 UDF 만들기:

CREATE FUNCTION multiply1 (a number, b number)
  RETURNS number
  COMMENT='multiply two numbers'
  AS 'a * b';
Copy

쿼리의 결과를 반환하고 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';
Copy