UDFs의 개요

이 항목에서는 UDFs(사용자 정의 함수)에 적용되는 개념 및 사용 세부 정보를 다룹니다.

이 항목의 내용:

스칼라 대 테이블 형식 UDFs

UDFs는 스칼라 또는 테이블 형식일 수 있습니다.

스칼라 함수는 각 입력 행에 대해 하나의 출력 행을 반환합니다. 반환된 행은 단일 열/값으로 구성됩니다.

스칼라 UDF 만들기와 사용에 대한 자세한 내용은 다음을 참조하십시오.

테이블 함수 라고도 하는 테이블 형식 함수는 각 입력 행에 대해 0개, 1개 또는 여러 개의 행을 반환합니다. 테이블 형식 UDF는 TABLE 키워드를 포함하고 테이블 결과에 있는 열의 이름과 데이터 타입을 지정하는 반환 절을 지정하여 정의됩니다. 테이블 형식 UDFs를 종종 UDTFs (사용자 정의 테이블 함수) 또는 테이블 UDFs 라고 부릅니다.

예를 포함하여 UDTFs 만들기와 사용에 대한 자세한 내용은 다음을 참조하십시오.

UDFs를 만들기 위해 지원되는 프로그래밍 언어

Snowflake는 다음 프로그래밍 언어를 지원합니다.

SQL

SQL UDF는 스칼라 또는 테이블 형식 일 수 있습니다.

SQL UDF는 임의의 SQL 식을 평가하고 식의 결과를 반환합니다.

식은 일반 식 또는 쿼리 식일 수 있습니다.

  • 이 UDF는 일반 식 pi() * radius * radius 를 사용합니다.

    CREATE FUNCTION area_of_circle(radius FLOAT)
      RETURNS FLOAT
      AS
      $$
        pi() * radius * radius
      $$
      ;
    
  • 이 UDF는 쿼리 식을 사용합니다.

    CREATE FUNCTION profit()
      RETURNS NUMERIC(11, 2)
      AS
      $$
        SELECT SUM((retail_price - wholesale_price) * number_sold)
            FROM purchases
      $$
      ;
    

테이블 형식이 아닌 UDF의 경우 쿼리 식은 하나의 열을 포함하는 최대 하나의 행을 반환하도록 보장되어야 합니다.

UDF를 정의하는 식은 위의 예와 같이 함수의 입력 인자를 참조할 수 있습니다.

UDF를 정의하는 식은 위의 예와 같이 테이블, 뷰, 시퀀스와 같은 데이터베이스 오브젝트를 참조할 수 있습니다. 그러나 다음과 같은 제한 사항이 적용됩니다.

  • UDF 소유자 는 UDF가 액세스하는 모든 데이터베이스 오브젝트에 대해 적절한 권한이 있어야 합니다.

  • 데이터베이스 오브젝트는 동적 SQL을 사용하여 참조될 수 없습니다. 예를 들어 다음 문은 IDENTIFIER(table_name_parameter) 가 허용되지 않기 때문에 실패합니다.

    CREATE OR REPLACE FUNCTION profit2(table_name_parameter VARCHAR)
      RETURNS NUMERIC(11, 2)
      AS
      $$
        SELECT SUM((retail_price - wholesale_price) * number_sold)
            FROM IDENTIFIER(table_name_parameter)
      $$
      ;
    

UDF를 정의하는 식은 문 종결자로 세미콜론을 포함하지 않아야 합니다. 예를 들어, 위 쿼리 식 UDF의 SELECT 는 세미콜론으로 끝나지 않습니다.

SQL UDF의 정의 식은 다른 사용자 정의 함수를 참조할 수 있습니다. 그러나 직접 또는 간접적으로(즉, 이 식을 다시 호출하는 다른 함수를 통해) 자신을 재귀적으로 참조할 수는 없습니다.

자세한 내용은 SQL UDF 소개 섹션을 참조하십시오.

JavaScript

JavaScript UDFs를 통해 JavaScript 프로그래밍 언어와 런타임 환경을 사용하여 데이터를 조작할 수 있습니다. JavaScript UDFs는 SQL UDFs와 같은 방식으로 생성되지만, LANGUAGE 매개 변수가 JAVASCRIPT로 설정됩니다.

SQL UDFs와 유사하게, JavaScript UDFs는 UDF를 정의하는 방식에 따라 스칼라 또는 테이블 형식의 결과를 반환할 수 있습니다.

JavaScript UDF의 정의 식은 자신을 재귀적으로 참조할 수 있지만, 다른 사용자 정의 함수는 참조할 수 없습니다.

자세한 내용은 JavaScript UDF 소개 섹션을 참조하십시오.

참고

JavaScript UDFs는 SQL UDFs에는 적용되지 않는 몇 가지 요구 사항, 사용 세부 사항, 제한 사항이 있습니다. 예를 포함한 자세한 내용은 JavaScript UDTF 쓰기 섹션을 참조하십시오.

Java

Java UDFs를 통해 Java 프로그래밍 언어와 런타임 환경을 사용하여 데이터를 조작할 수 있습니다.

SQL 및 JavaScript UDF와 유사하게, Java UDF는 UDF를 정의하는 방식에 따라 스칼라 또는 테이블 형식의 결과를 반환할 수 있습니다.

다음 두 가지 방법 중 하나로 Java UDFs를 만들 수 있습니다.

  • 인라인: CREATE FUNCTION 명령의 일부로 Java 코드를 입력합니다.

  • JAR 파일: 이미 컴파일된 JAR 파일의 위치를 CREATE FUNCTION 명령의 일부로 지정합니다.

자세한 내용은 Java UDF 소개 섹션을 참조하십시오.

참고

Java UDFs는 SQL UDFs에는 적용되지 않는 몇 가지 요구 사항, 사용 세부 사항, 제한 사항이 있습니다. 자세한 내용은 다음을 참조하십시오.

Python

Python UDF를 통해 Python 프로그래밍 언어와 런타임 환경을 사용하여 데이터를 조작할 수 있습니다.

Java UDF와 유사하게, Python UDF는 UDF를 정의하는 방식에 따라 스칼라 또는 테이블 형식의 결과를 반환할 수 있습니다.

다음 두 가지 방법 중 하나로 Python UDF를 만들 수 있습니다.

  • 인라인으로: CREATE FUNCTION 명령의 일부로 Python 코드를 입력합니다.

  • 스테이지dp 복사된 모듈로: CREATE FUNCTION 명령의 일부로 모듈 파일의 위치를 지정합니다.

자세한 내용은 Python UDF 소개 섹션을 참조하십시오.

참고

Python UDF는 SQL UDF에는 적용되지 않는 몇 가지 요구 사항, 사용 세부 사항, 제한 사항이 있습니다. 자세한 내용은 다음을 참조하십시오.

프로그래밍 언어 선택하기

UDF 작성에 사용하는 프로그래밍 언어에 영향을 미칠 수 있는 요인이 많습니다. 다음과 같은 요인이 있을 수 있습니다.

  • 특정 언어로 된 코드가 이미 있는지 여부. 예를 들어, 필요한 작업을 수행하는 메서드가 포함된 .jar 파일이 이미 있는 경우에는 Java를 프로그래밍 언어로 선호할 수 있습니다.

  • 언어의 기능.

  • 언어에 수행해야 할 처리 작업의 수행에 도움이 될 수 있는 라이브러리가 있는지 여부.

다음 표에 각 UDF 프로그래밍 언어의 주요 기능이 요약되어 있습니다. 아래 목록에 테이블의 열에 대해 설명되어 있습니다.

  • 테이블 형식: (스칼라 함수 외에) Snowflake가 테이블 함수 작성을 지원하는지 여부를 나타냅니다.

  • 루핑 및 분기: 프로그래밍 언어가 루핑과 분기를 지원하는지 여부를 나타냅니다.

  • 미리 컴파일됨: UDF에 대한 코드를 컴파일된 파일(예: .JAR파일)로 제공할 수 있는지 여부를 나타냅니다.

  • 인라인: CREATE FUNCTION 문에서 코드를 텍스트로 제공할 수 있는지 여부를 나타냅니다.

  • 공유 가능: 이 언어로 작성된 UDFs를 Snowflake Secure Data Sharing 기능과 함께 사용할 수 있는지 여부를 나타냅니다.

언어

테이블 형식

루핑 및 분기

미리 컴파일되거나 스테이징된 원본

인라인

공유 가능

SQL

아니요

아니요

JavaScript

아니요

Java

예(미리 컴파일됨)

아니요 1

Python

예(스테이징됨)

아니요 2

1

Java UDFs 공유 제한에 대한 자세한 내용은 Java UDF에 대한 제한 사항 을 참조하십시오.

2

Python UDF 공유 제한에 대한 자세한 내용은 Python UDF에 대한 제한 사항 을 참조하십시오.

UDFs의 명명 규칙

UDFs는 데이터베이스 오브젝트인데, 이는 곧 저장 프로시저가 지정된 데이터베이스와 스키마에서 생성된다는 뜻입니다. 이와 같이, UDF는 db.schema.function_name 형식의 네임스페이스로 정의된 정규화된 이름을 가집니다. 예:

SELECT temporary_db_qualified_names_test.temporary_schema_1.udf_pi();

정규화된 이름 없이 호출 시는 UDFs가 세션에 사용 중인 데이터베이스와 스키마에 따라 확인됩니다.

이는 Snowflake에서 제공하는 기본 제공 시스템 정의 함수(네임스페이스가 없어 어디서나 호출할 수 있음)와 대비되는 점입니다.

시스템 정의 함수와의 충돌

함수 호출 시 충돌을 피하기 위해, Snowflake에서는 시스템 정의 함수와 같은 이름을 가진 UDFs를 만들 수 없습니다.

UDF 이름의 오버로딩

Snowflake는 SQL UDF 이름의 오버로딩을 지원합니다. 같은 스키마에 있는 여러 SQL UDFs는 인자 서명이 다른 한 인자의 개수나 인자 유형을 기준으로 같은 이름을 가질 수 있습니다. 오버로드된 UDF가 호출될 때 Snowflake는 인자를 확인하고 올바른 함수를 호출합니다.

add5 로 명명된 두 SQL UDFs를 만드는 다음 예를 생각해보십시오.

CREATE OR REPLACE FUNCTION add5 (n number)
  RETURNS number
  AS 'n + 5';

CREATE OR REPLACE FUNCTION add5 (s string)
  RETURNS string
  AS 's || ''5''';

중요

두 번째 ADD5 함수에서 작은따옴표는 문자열 리터럴 '5' 를 이스케이프하는 데 사용됩니다. UDF 정의에 사용되는 작은따옴표는 모두 작은따옴표로 이스케이프 해야 합니다.

add5 를 숫자 인자와 함께 호출하는 경우에는 첫 번째 구현을 선택하는 반면, 문자열 형식의 인자는 두 번째 구현을 사용합니다. 인자가 숫자도 문자열도 아닌 경우에는 구현이 Snowflake의 암시적 형식 변환 규칙에 따라 달라집니다. 예를 들어, 날짜 형식의 인자는 문자열로 변환되며, DATE에서 NUMBER로의 변환이 지원되지 않으므로 문자열 구현이 선택됩니다.

예:

select add5(1);

+---------+
| ADD5(1) |
|---------|
|       6 |
+---------+

select add5('1');

+-----------+
| ADD5('1') |
|-----------|
| 15        |
+-----------+

select add5('hello');

+---------------+
| ADD5('HELLO') |
|---------------|
| hello5        |
+---------------+

select add5(to_date('2014-01-01'));

+-----------------------------+
| ADD5(TO_DATE('2014-01-01')) |
|-----------------------------|
| 2014-01-015                 |
+-----------------------------+

오버로딩을 사용할 때는 주의하십시오. 자동 형식 변환과 오버로딩이 합쳐지면 사소한 사용자 오류로 인해 예기치 않은 결과가 발생하기 쉽습니다. 예를 보려면 함수 이름 오버로딩하기 를 참조하십시오.

조심

SQL 이외의 언어로 작성한 UDFs에 대해서는 규칙이 다를 수 있습니다.

함수 이름 오버로딩하기

(이 항목의) UDF 이름의 오버로딩 에서 설명한 대로, 함수 이름을 오버로딩할 수 있습니다.

다음 오버로딩 예에서는 오버로딩과 자동 형식 변환을 결합하여 예기치 않은 결과를 쉽게 얻을 수 있게 만드는 방법을 보여줍니다.

FLOAT 매개 변수를 받는 함수를 만듭니다.

CREATE FUNCTION add_pi(PARAM_1 FLOAT)
    RETURNS FLOAT
    LANGUAGE SQL
    AS $$
        PARAM_1 + 3.1415926::FLOAT
    $$;

이 함수를 두 번 호출합니다. 처음 호출할 때는 FLOAT를 전달합니다. 두 번째로 호출할 때는 VARCHAR를 전달합니다. VARCHAR는 FLOAT로 변환되고, 각 호출에서 출력이 같습니다.

SELECT add_pi(1.0), add_pi('1.0');
+-------------+---------------+
| ADD_PI(1.0) | ADD_PI('1.0') |
|-------------+---------------|
|   4.1415926 |     4.1415926 |
+-------------+---------------+

이제 VARCHAR 매개 변수를 받는 오버로드된 함수를 만듭니다.

CREATE FUNCTION add_pi(PARAM_1 VARCHAR)
    RETURNS VARCHAR
    LANGUAGE SQL
    AS $$
        PARAM_1 || ' + 3.1415926'
    $$;

이제는 전과 정확히 똑같은 CALLs을 사용합니다. 이 두 개의 CALLs과 이전의 두 CALLs 사이에서 출력의 차이점에 유의하십시오.

SELECT add_pi(1.0), add_pi('1.0');
+-------------+-----------------+
| ADD_PI(1.0) | ADD_PI('1.0')   |
|-------------+-----------------|
|   4.1415926 | 1.0 + 3.1415926 |
+-------------+-----------------+
맨 위로 이동