Snowflake Scripting UDFs

Snowflake는 Snowflake Scripting 프로시저 언어가 포함된 SQL 사용자 정의 함수(UDFs)를 지원합니다. 이러한 UDFs를 *Snowflake Scripting UDFs*라고 합니다.

Snowflake Scripting UDFs는 SQL 문(예: SELECT 문 또는 INSERT 문)에서 호출할 수 있습니다. 따라서 SQL CALL 명령에서만 호출할 수 있는 Snowflake Scripting 저장 프로시저보다 더 유연합니다.

일반 사용

Snowflake Scripting UDF는 프로시저 코드를 평가하고 스칼라(즉, 단일) 값을 반환합니다.

Snowflake Scripting UDFs에서 다음과 같은 Snowflake Scripting 구문의 하위 세트를 사용할 수 있습니다.

지원되는 데이터 타입

Snowflake Scripting UDFs는 입력 인자와 반환 값 모두에 대해 다음 데이터 타입을 지원합니다.

  • :doc:`/sql-reference/data-types-numeric`(예: INTEGER, NUMBER, FLOAT)

  • 문자열 및 이진 데이터 타입 (예: VARCHAR 및 BINARY)

  • :doc:`/sql-reference/data-types-datetime`(예: DATE, TIME, TIMESTAMP)

  • :doc:`/sql-reference/data-types-logical`(예: BOOLEAN)

Snowflake Scripting UDFs는 입력 인자에 대해서만 다음 데이터 타입을 지원합니다.

  • :doc:`/sql-reference/data-types-semistructured`(예: VARIANT, OBJECT, ARRAY)

  • :doc:`/sql-reference/data-types-structured`(예: ARRAY, OBJECT, MAP)

제한 사항

Snowflake Scripting UDFs에는 다음과 같은 제한 사항이 적용됩니다.

  • 다음과 같은 유형의 Snowflake Scripting 구문은 Snowflake Scripting UDFs에서 지원되지 않습니다.

  • SQL 문은 Snowflake Scripting UDFs에서 지원되지 않습니다(SELECT, INSERT, UPDATE 등 포함).

  • Snowflake Scripting UDFs는 테이블 함수로 정의할 수 없습니다.

  • 다음 표현식 유형은 Snowflake Scripting UDFs에서 지원되지 않습니다.

    • 사용자 정의 함수

    • 집계 함수

    • 윈도우 함수

  • Snowflake Scripting UDFs는 구체화된 뷰를 만들 때 사용할 수 없습니다.

  • Snowflake Scripting UDFs는 행 액세스 정책 및 마스킹 정책을 만들 때 사용할 수 없습니다.

  • Snowflake Scripting UDFs는 기본 열 값을 지정하는 데 사용할 수 없습니다.

  • Snowflake Scripting UDFs는 데이터를 로딩/언로딩하기 위한 COPY INTO 명령에 사용할 수 없습니다.

  • Snowflake Scripting UDFs는 메모이제이션 불가능합니다.

  • Snowflake Scripting UDFs의 입력 인자는 500개로 제한됩니다.

  • Snowflake Scripting UDFs용 :doc:`메시지를 로깅 </developer-guide/logging-tracing/logging>`할 수 없습니다.

다음 예제에서는 Snowflake Scripting UDFs를 만들고 호출합니다.

변수를 사용하여 Snowflake Scripting UDF 만들기

두 인자의 값을 기반으로 이익을 계산하는 Snowflake Scripting UDF를 만듭니다.

CREATE OR REPLACE FUNCTION calculate_profit(
  cost NUMBER(38, 2),
  revenue NUMBER(38, 2))
RETURNS number(38, 2)
LANGUAGE SQL
AS
DECLARE
  profit NUMBER(38, 2) DEFAULT 0.0;
BEGIN
  profit := revenue - cost;
  RETURN profit;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

쿼리에서 ``calculate_profit``을 호출합니다.

SELECT calculate_profit(100, 110);
Copy
+----------------------------+
| CALCULATE_PROFIT(100, 110) |
|----------------------------|
|                      10.00 |
+----------------------------+

동일한 Snowflake Scripting UDF를 사용하고 인자의 열을 지정합니다. 먼저 테이블을 만들고 데이터를 삽입합니다.

CREATE OR REPLACE TABLE snowflake_scripting_udf_profit(
  cost NUMBER(38, 2),
  revenue NUMBER(38, 2));

INSERT INTO snowflake_scripting_udf_profit VALUES
  (100, 200),
  (200, 190),
  (300, 500),
  (400, 401);
Copy

쿼리에서 ``calculate_profit``을 호출하고 인자의 열을 지정합니다.

SELECT calculate_profit(cost, revenue)
  FROM snowflake_scripting_udf_profit;
Copy
+---------------------------------+
| CALCULATE_PROFIT(COST, REVENUE) |
|---------------------------------|
|                          100.00 |
|                          -10.00 |
|                          200.00 |
|                            1.00 |
+---------------------------------+

조건부 논리를 사용하여 Snowflake Scripting UDF 만들기

조건부 논리를 사용하여 입력 INTEGER 값을 기준으로 부서 이름을 결정하는 Snowflake Scripting UDF를 만듭니다.

CREATE OR REPLACE function check_dept(department_id INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
BEGIN
  IF (department_id < 3) THEN
    RETURN 'Engineering';
  ELSEIF (department_id = 3) THEN
    RETURN 'Tool Design';
  ELSE
    RETURN 'Marketing';
  END IF;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

쿼리에서 ``check_dept``을 호출합니다.

SELECT check_dept(2);
Copy
+---------------+
| CHECK_DEPT(2) |
|---------------|
| Engineering   |
+---------------+

Snowflake Scripting UDF를 호출할 때 인자에 SQL 변수</sql-reference/session-variables>`를 사용할 수 있습니다. 다음 예제에서는 SQL 변수를 설정한 후 ``check_dept` UDF 호출에 해당 변수를 사용합니다.

SET my_variable = 3;

SELECT check_dept($my_variable);
Copy
+--------------------------+
| CHECK_DEPT($MY_VARIABLE) |
|--------------------------|
| Tool Design              |
+--------------------------+

루프를 사용하여 Snowflake Scripting UDF 만들기

루프를 사용하여 인자에 제공된 대상 숫자까지 모든 숫자를 계산하고, 계산된 모든 숫자의 합계를 계산하는 Snowflake Scripting UDF를 만듭니다.

CREATE OR REPLACE function count_to(
  target_number INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
DECLARE
  counter INTEGER DEFAULT 0;
  sum_total INTEGER DEFAULT 0;
BEGIN
  WHILE (counter < target_number) DO
    counter := counter + 1;
    sum_total := sum_total + counter;
  END WHILE;
  RETURN 'Counted to ' || counter || '. Sum of all numbers: ' || sum_total;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

쿼리에서 ``count_to``을 호출합니다.

SELECT count_to(10);
Copy
+---------------------------------------+
| COUNT_TO(10)                          |
|---------------------------------------|
| Counted to 10. Sum of all numbers: 55 |
+---------------------------------------+

예외 처리를 사용하여 Snowflake Scripting UDF 만들기

예외를 선언한 후 예외를 발생시키는 Snowflake Scripting UDF를 만듭니다.

CREATE OR REPLACE FUNCTION raise_exception(input_value INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
DECLARE
  counter_val INTEGER DEFAULT 0;
  my_exception EXCEPTION (-20002, 'My exception text');
BEGIN
  WHILE (counter_val < 12) DO
    counter_val := counter_val + 1;
    IF (counter_val > 10) THEN
      RAISE my_exception;
    END IF;
  END WHILE;
  RETURN counter_val;
EXCEPTION
  WHEN my_exception THEN
    IF (input_value = 1) THEN
      RETURN 'My exception caught: ' || sqlcode;
    ELSEIF (input_value = 2) THEN
      RETURN 'My exception caught with different path: ' || sqlcode;
    END IF;
    RETURN 'Default exception handling path: ' || sqlcode;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

쿼리에서 ``raise_exception``을 호출하고 입력 값에 ``1``을 지정합니다.

SELECT raise_exception(1);
Copy
+-----------------------------+
| RAISE_EXCEPTION(1)          |
|-----------------------------|
| My exception caught: -20002 |
+-----------------------------+

쿼리에서 ``raise_exception``을 호출하고 입력 값에 ``2``을 지정합니다.

SELECT raise_exception(2);
Copy
+-------------------------------------------------+
| RAISE_EXCEPTION(2)                              |
|-------------------------------------------------|
| My exception caught with different path: -20002 |
+-------------------------------------------------+t

쿼리에서 ``raise_exception``을 호출하고 입력 값에 ``NULL``을 지정합니다.

SELECT raise_exception(NULL);
Copy
+-----------------------------------------+
| RAISE_EXCEPTION(NULL)                   |
|-----------------------------------------|
| Default exception handling path: -20002 |
+-----------------------------------------+

INSERT 문의 값을 반환하는 Snowflake Scripting UDF를 만듭니다.

INSERT 문에 사용되는 값을 반환하는 Snowflake Scripting UDF를 만듭니다. 값을 삽입할 테이블을 만듭니다.

CREATE OR REPLACE TABLE test_sql_udf_insert (num NUMBER);
Copy

숫자 값을 반환하는 SQL UDF를 만듭니다.

CREATE OR REPLACE FUNCTION value_to_insert(l NUMBER, r NUMBER)
RETURNS number
LANGUAGE SQL
AS
BEGIN
  IF (r < 0) THEN
    RETURN l/r * -1;
  ELSEIF (r > 0) THEN
    RETURN l/r;
  ELSE
    RETURN 0;
END IF;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

여러 INSERT 문에서 ``value_to_insert``를 호출합니다.

INSERT INTO test_sql_udf_insert SELECT value_to_insert(10, 2);
INSERT INTO test_sql_udf_insert SELECT value_to_insert(10, -2);
INSERT INTO test_sql_udf_insert SELECT value_to_insert(10, 0);
Copy

테이블을 쿼리하여 삽입된 값을 확인합니다.

SELECT * FROM test_sql_udf_insert;
Copy
+-----+
| NUM |
|-----|
|   5 |
|   5 |
|   0 |
+-----+

WHERE 및 ORDER BY 절에서 호출된 Snowflake Scripting UDF 만들기

WHERE 또는 ORDER BY 절에서 사용되는 값을 반환하는 Snowflake Scripting UDF를 만듭니다. 테이블을 만들고 값을 삽입합니다.

CREATE OR REPLACE TABLE test_sql_udf_clauses (p1 INT, p2 INT);

INSERT INTO test_sql_udf_clauses VALUES
  (100, 7),
  (100, 3),
  (100, 4),
  (NULL, NULL);
Copy

두 입력 값을 곱한 결과인 숫자 값을 반환하는 SQL UDF를 만듭니다.

CREATE OR REPLACE FUNCTION get_product(a INTEGER, b INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
BEGIN
  RETURN a * b;
END;
Copy

참고

Snowflake CLI, SnowSQL, Classic Console 또는 execute_stream`이나 :code:`execute_string 메서드를 Python Connector 코드에서 사용하는 경우 이 예제를 약간 변경해야 합니다. 자세한 내용은 Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 섹션을 참조하십시오.

쿼리의 WHERE 절에서 ``get_product``를 호출하여 곱이 ``350``보다 큰 행을 반환합니다.

SELECT *
  FROM test_sql_udf_clauses
  WHERE get_product(p1, p2) > 350;
Copy
+-----+----+
|  P1 | P2 |
|-----+----|
| 100 |  7 |
| 100 |  4 |
+-----+----+

쿼리의 ORDER BY 절에서 ``get_product``를 호출하여 UDF에서 반환된 곱 중 가장 작은 값부터 가장 큰 값 순서로 정렬합니다.

SELECT *
  FROM test_sql_udf_clauses
  ORDER BY get_product(p1, p2);
Copy
+------+------+
|  P1  | P2   |
|------+------|
| 100  | 3    |
| 100  | 4    |
| 100  | 7    |
| NULL | NULL |
+------+------+