SnowConvert AI - Oracle - CREATE FUNCTION

Oracle Create 함수를 Snowflake Snow Scripting으로 변환

설명

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

저장 함수 (사용자 함수 또는 사용자 정의 함수)는 이름으로 호출할 수 있는 PL/SQL 문의 집합입니다. 저장 프로시저는 함수가 호출된 환경에 값을 반환한다는 점을 제외하고는 프로시저와 매우 유사합니다. 사용자 함수는 SQL 식의 일부로 사용할 수 있습니다.

호출 명세 는 Java 메서드 또는 3세대 언어(3GL) 루틴을 선언하여 PL/SQL 에서 호출할 수 있도록 합니다. CALL SQL 문을 사용하여 이러한 메서드나 루틴을 호출할 수도 있습니다. 호출 사양은 호출이 수행될 때 어떤 Java 메서드 또는 공유 라이브러리의 어떤 명명된 함수를 호출할지 Oracle 데이터베이스에 알려줍니다. 또한 데이터베이스에 인자 및 반환 값에 대해 어떤 유형 변환을 수행할지 알려줍니다. Oracle SQL Language Reference 생성 함수.

Oracle 구문

Oracle Create 함수에 대한 자세한 내용은 여기 에서 확인할 수 있습니다.

Oracle Create 함수 구문

CREATE [ OR REPLACE ] [ EDITIONABLE | NONEDITIONABLE ]
FUNCTION
[ schema. ] function_name
  [ ( parameter_declaration [, parameter_declaration]... ) ] RETURN datatype 
[ sharing_clause ]
  [ { invoker_rights_clause
    | accessible_by_clause
    | default_collation_clause    
    | deterministic_clause
    | parallel_enable_clause
    | result_cache_clause 
    | aggregate_clause
    | pipelined_clause
    | sql_macro_clause
       }...
  ]
{ IS | AS } { [ declare_section ] 
    BEGIN statement ...
    [ EXCEPTION exception_handler [ exception_handler ]... ]
    END [ name ] ;
      |
    { java_declaration | c_declaration } } ;
Copy

Snowflake 구문

Snowflake는 사용자 정의 함수에서 3가지 언어를 지원합니다.

  • SQL

  • JavaScript

  • Java

현재, SnowConvert AI는 SQLJavaScript만 대상 언어로 지원합니다.

Snowflake Create 함수에 대한 자세한 내용은 여기 에서 확인할 수 있습니다.

SQL

참고

SQL 사용자 정의 함수는 본문으로 1개의 쿼리만 지원합니다. 데이터베이스에서 읽을 수는 있지만 쓰거나 수정할 수는 없습니다(스칼라 SQL UDFs).

CREATE [ OR REPLACE ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
  [ [ NOT ] NULL ]
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ VOLATILE | IMMUTABLE ]
  [ COMMENT = '<string_literal>' ]
  AS '<function_definition>'
Copy
JavaScript

참고

JavaScript 사용자 정의 함수는 본문에 여러 문을 허용하지만 데이터베이스 쿼리를 수행할 수는 없습니다. (스칼라 JavaScript UDFs).

CREATE [ OR REPLACE ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  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

샘플 소스 패턴

샘플 보조 데이터

참고

이 코드는 예제를 더 잘 이해하기 위해 실행한 것입니다.

Oracle

CREATE TABLE table1 (col1 int, col2 int, col3 varchar2(250), col4 varchar2(250), col5 date);

INSERT INTO table1 VALUES (1, 11, 'val1_1', 'val1_2', TO_DATE('2004/05/03', 'yyyy-MM-dd'));
INSERT INTO table1 VALUES (2, 22, 'val2_1', 'val2_2', TO_DATE('2014/05/03', 'yyyy-MM-dd'));
INSERT INTO table1 VALUES (3, 33, 'val3_1', 'val3_2', TO_DATE('2024/05/03', 'yyyy-MM-dd'));
Copy
Snowflake
CREATE OR REPLACE TABLE table1 (col1 int,
col2 int,
col3 VARCHAR(250),
col4 VARCHAR(250),
col5 TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "07/25/2024" }}'
;

INSERT INTO table1
VALUES (1, 11, 'val1_1', 'val1_2', TO_DATE('2004/05/03', 'yyyy-MM-dd'));

INSERT INTO table1
VALUES (2, 22, 'val2_1', 'val2_2', TO_DATE('2014/05/03', 'yyyy-MM-dd'));

INSERT INTO table1
VALUES (3, 33, 'val3_1', 'val3_2', TO_DATE('2024/05/03', 'yyyy-MM-dd'));
Copy

Known Issues

문제가 발견되지 않았습니다.

반환 변수에 대한 커서

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

이 패턴은 커서를 사용하여 단일 값을 가져와 반환하는 함수를 Oracle PL/SQL 에서 정의합니다.

구성 요소:

  1. 함수 선언:

    • CREATE FUNCTION functionName(parameters) RETURN returnType

    • 입력 매개 변수와 반환 유형으로 함수를 선언합니다.

  2. 변수 선언:

    • 반환 변수를 포함한 변수를 선언합니다.

  3. 커서 선언:

    • CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];

    • 선택적 필터링 조건이 있는 테이블에서 단일 열을 선택하는 커서를 정의합니다.

  4. BEGIN-END 블록:

    • 변수 할당.

    • 커서를 엽니다.

    • 결과를 반환 변수로 가져옵니다.

    • 커서를 닫습니다.

    • 가져온 값을 반환합니다.

이 경우 변수는 공통 테이블 식(CTE)으로 변환됩니다. 커서 내의 쿼리에 추가로 FETCH FIRST 1 ROW ONLY 절을 추가하여 FETCH CURSOR 의 동작을 시뮬레이션합니다.

RETURN 문이 최종 선택 문으로 변환됩니다.

쿼리

Oracle

CREATE OR REPLACE FUNCTION func1 (
   company_ IN VARCHAR2,
   book_id_ IN DATE,
   object_id_ IN VARCHAR2 ) RETURN INTEGER
IS
   temp_ table1.col2%TYPE;
   CURSOR get_attr IS
      SELECT col2
      FROM table1
      WHERE col3 = company_
      AND   col4 = object_id_
      AND   col5 = book_id_;
BEGIN
   OPEN get_attr;
   FETCH get_attr INTO temp_;
   CLOSE get_attr;
   RETURN temp_;
END func1;
Copy
Snowflake
CREATE OR REPLACE FUNCTION func1 (company_ VARCHAR, book_id_ TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/, object_id_ VARCHAR)
RETURNS INTEGER
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte1 AS
   (
      SELECT
         (
         SELECT col2
         FROM table1
         WHERE col3 = company_
         AND   col4 = object_id_
         AND   col5 = book_id_
         FETCH FIRST 1 ROW ONLY) AS temp_
   )
   SELECT
      temp_
   FROM
      declaration_variables_cte1
$$;
Copy
결과

FUNC1()

2004-05-03.

Oracle
CREATE FUNCTION func2 (
   fa_period_   IN NUMBER,
   to_date_     IN DATE DEFAULT NULL,
   from_date_   IN DATE DEFAULT NULL ) RETURN NUMBER
IS
   value_                    NUMBER;
   cond_date_to_             DATE;
   cond_date_from_           DATE;
   CURSOR get_acq_value IS
      SELECT NVL(SUM(col1),0)
      FROM   table1
      WHERE  col3                   IN (DECODE(fa_period_, 1, 'val1_1', 'val2_1'))
      AND    col5           <= cond_date_to_
      AND    col5           >= cond_date_from_;
BEGIN
   value_ := 0;
   cond_date_to_       := Get_Cond_Date( to_date_, 'MAX' );
   cond_date_from_     := Get_Cond_Date( from_date_, 'MIN' );
   OPEN get_acq_value;
   FETCH get_acq_value INTO value_;
   CLOSE get_acq_value;
   RETURN (NVL(value_,0));
END func2;
Copy
Snowflake
CREATE OR REPLACE FUNCTION func2 (fa_period_ NUMBER(38, 18),
  to_date_ TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/ DEFAULT NULL,
  from_date_ TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/ DEFAULT NULL )
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte1 AS
   (
      SELECT
         0 AS
         value_,
         Get_Cond_Date( to_date_, 'MAX' ) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Get_Cond_Date' NODE ***/!!! AS
         cond_date_to_,
         Get_Cond_Date( from_date_, 'MIN' ) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Get_Cond_Date' NODE ***/!!! AS
         cond_date_from_
   ),
   declaration_variables_cte2 AS
   (
      SELECT
         (
         SELECT NVL(SUM(col1),0)
         FROM   table1
         WHERE  col3                   IN (DECODE(fa_period_, 1, 'val1_1', 'val2_1'))
         AND    col5           <= cond_date_to_
         AND    col5           >= cond_date_from_
         FETCH FIRST 1 ROW ONLY) AS value_,
         cond_date_to_,
         cond_date_from_
      FROM
         declaration_variables_cte1
   )
   SELECT
      (NVL(value_,0))
   FROM
      declaration_variables_cte2
$$;
Copy
결과

FUNC1()

2004-05-03.

Known Issues

문제가 발견되지 않았습니다.

관련 EWIS

  1. SSC-FDM-OR0042: 타임스탬프로 변환된 날짜 유형의 동작이 다릅니다.

  2. SSC-EWI-0073: 보류 중 함수 동등성 검토.

IF 문이 있는 커서

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

이 패턴은 조건부로 커서를 사용하여 IF 문을 기반으로 값을 가져와 반환하는 함수를 정의합니다.

구성 요소:

  1. 함수 선언:

    • CREATE FUNCTION functionName(parameters) RETURN returnType

    • 입력 매개 변수와 반환 유형으로 함수를 선언합니다.

  2. 커서 선언:

    • CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];

    • 선택적 필터링 조건이 있는 테이블에서 단일 열을 선택하는 커서를 정의합니다.

  3. 변수 선언:

    • 반환 변수를 포함한 변수를 선언합니다.

  4. IF 문이 있는 BEGIN-END 블록:

    • 변수 할당.

    • 조건이 true인지 확인합니다.

    • true이면 커서를 열고 결과를 반환 변수로 가져온 다음 커서를 닫고 가져온 값을 반환합니다. (커서는 ELSE 블록에서도 열 수 있으며 동일한 조건을 충족해야 합니다.)

    • ELSE 블록은 선택 사항이며, 존재하는 경우 할당 또는 RETURN 문이 될 수 있는 단일 문만 포함해야 합니다.

변수는 공통 테이블 식(CTE)으로 변환됩니다. 커서 내의 쿼리에 추가로 FETCH FIRST 1 ROW ONLY 절을 추가하여 FETCH CURSOR 의 동작을 시뮬레이션합니다.

IF/ELSE 문은 쿼리 내에서 조건문을 허용하는 select 내에 CASE EXPRESSION를 사용하여 처리할 수 있습니다. RETURN 문은 최종 select…로 변환됩니다.

쿼리

Oracle

CREATE OR REPLACE FUNCTION func1 (
   company_          IN NUMBER) RETURN NUMBER
IS
   CURSOR getmaxperiod IS
      SELECT max(col2)
      FROM   table1;
   max_period_               NUMBER := 12;
BEGIN
   IF 1 = 1 THEN
      OPEN   getmaxperiod;
      FETCH  getmaxperiod INTO max_period_ ;
      CLOSE  getmaxperiod;
      RETURN max_period_;
   ELSE
      RETURN NULL;
   END IF;
END func1;
Copy
Snowflake
CREATE OR REPLACE FUNCTION func1 (company_ NUMBER(38, 18))
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte0 AS
   (
      SELECT
         12 AS
         max_period_
   ),
   declaration_variables_cte1 AS
   (
      SELECT
         CASE
            WHEN 1 = 1
               THEN (
               SELECT max(col2)
               FROM   table1
               FETCH FIRST 1 ROW ONLY)
            ELSE NULL
         END AS max_period_
      FROM
         declaration_variables_cte0
   )
   SELECT
      max_period_
   FROM
      declaration_variables_cte1
$$;
Copy
결과

FUNC2(0)

NULL

FUNC2(1)

33

Oracle
CREATE OR REPLACE FUNCTION func2(
   company_          IN NUMBER) RETURN NUMBER
IS
   CURSOR getmaxperiod IS
      SELECT max(col2)
      FROM   table1;
   max_period_               NUMBER := 1;
BEGIN
   max_period_:= 2;
   IF company_ = 1 THEN
      RETURN max_period_ * 2;
   ELSE
      OPEN   getmaxperiod;
      FETCH  getmaxperiod INTO max_period_ ;
      CLOSE  getmaxperiod;
      RETURN max_period_;
   END IF;
END func2;
Copy
Snowflake
CREATE OR REPLACE FUNCTION func2 (company_ NUMBER(38, 18))
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte0 AS
   (
      SELECT
         1 AS
         max_period_
   ),
   declaration_variables_cte1 AS
   (
      SELECT
         2 AS
         max_period_
      FROM
         declaration_variables_cte0
   ),
   declaration_variables_cte2 AS
   (
      SELECT
         CASE
            WHEN company_ = 1
               THEN max_period_ * 2
            ELSE (
            SELECT max(col2)
            FROM   table1
            FETCH FIRST 1 ROW ONLY)
         END AS max_period_
      FROM
         declaration_variables_cte1
   )
   SELECT
      max_period_
   FROM
      declaration_variables_cte2
$$;
Copy
결과

FUNC2(0)

33

FUNC2(1)

2

Oracle
CREATE OR REPLACE FUNCTION func3 (
   company_          IN NUMBER) RETURN NUMBER
IS
   CURSOR getmaxperiod IS
      SELECT max(col2)
      FROM   table1;
   max_period_               NUMBER := 0;
BEGIN
   IF company_ = 1 THEN
      OPEN   getmaxperiod;
      FETCH  getmaxperiod INTO max_period_ ;
      CLOSE  getmaxperiod;
   END IF;
   RETURN max_period_;
END func10;
Copy
Snowflake
CREATE OR REPLACE FUNCTION func3 (company_ NUMBER(38, 18))
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte0 AS
   (
      SELECT
         0 AS
         max_period_
   ),
   declaration_variables_cte1 AS
   (
      SELECT
         CASE
            WHEN company_ = 1
               THEN (
               SELECT max(col2)
               FROM   table1
               FETCH FIRST 1 ROW ONLY)
            ELSE max_period_
         END AS max_period_
      FROM
         declaration_variables_cte0
   )
   SELECT
      max_period_
   FROM
      declaration_variables_cte1
$$;
Copy
결과

FUNC2(0)

0

FUNC2(1)

33

Known Issues

문제가 발견되지 않았습니다.

관련 EWIS

EWIs 관련 없음.

여러 IFs 문

이 패턴은 로컬 변수에 조건문을 사용하는 함수를 정의합니다.

구성 요소:

  1. 함수 선언:

    • CREATE FUNCTION functionName(parameters) RETURN returnType

    • 입력 매개 변수와 반환 유형으로 함수를 선언합니다.

  2. 변수 선언:

    • 반환 변수를 포함한 변수를 선언합니다.

  3. IF 문이 있는 BEGIN-END 블록:

    • 조건이 true인지 확인합니다.

    • 각 케이스는 동일한 변수에 값을 할당하는 데 사용됩니다.

변환:

DECLARE SECTION : 기본 식이 있는 변수는 공통 테이블 식으로 이동합니다.

IF/ELSE 문은 쿼리 내에서 조건문을 허용하는 select 내에 CASE EXPRESSION를 사용하여 처리할 수 있습니다.

RETURN 문이 최종 선택 문으로 변환됩니다.

Oracle

CREATE OR REPLACE FUNCTION Case1 (
   in_date_ IN DATE,
   min_max_ IN VARCHAR2 )
RETURN DATE
IS
   cond_date_  DATE := CURRENT_DATE;
BEGIN
   IF ( in_date_ IS NULL ) THEN
      IF ( min_max_ = 'MIN' ) THEN
         cond_date_ := FOO1();
      ELSE
         cond_date_ := FOO2();
      END IF;
   ELSE
      cond_date_ := TRUNC(in_date_);
   END IF;
   RETURN cond_date_;
END Case1;
Copy

Snowflake

CREATE OR REPLACE FUNCTION Case1 (in_date_ TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/, min_max_ VARCHAR)
RETURNS TIMESTAMP /*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte0 AS
   (
      SELECT
         CURRENT_DATE AS
         cond_date_
   ),
   declaration_variables_cte1 AS
   (
      SELECT
         CASE
            WHEN ( in_date_ IS NULL )
               THEN CASE
                  WHEN ( min_max_ = 'MIN' )
                     THEN FOO1() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO1' NODE ***/!!!
                  ELSE FOO2() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO2' NODE ***/!!!
               END
            ELSE TRUNC(in_date_, 'DD')
         END AS cond_date_
      FROM
         declaration_variables_cte0
   )
   SELECT
      cond_date_
   FROM
      declaration_variables_cte1
$$;
Copy

Oracle

CREATE OR REPLACE FUNCTION Case2 (
   year_        IN NUMBER,
   id           IN NUMBER) 
   RETURN VARCHAR2
IS
   base_value_        NUMBER;
   fully_depritiated_ VARCHAR2(5);
   residual_value_    NUMBER;
   acc_depr_prev_     NUMBER;
   acc_depr_          NUMBER;
BEGIN

   base_value_     := FOO1(year_, id);
   acc_depr_       := FOO2(year_, id);
   acc_depr_prev_  := FOO3(year_, id);
   residual_value_ := NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_);

   IF (residual_value_=0 AND base_value_!=0) THEN
      fully_depritiated_ := 'TRUE';
   ELSE
      fully_depritiated_ := 'FALSE';
   END IF;

   RETURN fully_depritiated_;
END Case2;
Copy

Snowflake

CREATE OR REPLACE FUNCTION Case2 (year_ NUMBER(38, 18), id NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte1 AS
   (
      SELECT
         FOO1(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO1' NODE ***/!!! AS

         base_value_,
         FOO2(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO2' NODE ***/!!! AS
         acc_depr_,
         FOO3(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO3' NODE ***/!!! AS
         acc_depr_prev_,
         !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '-' MAY NOT BEHAVE CORRECTLY BETWEEN NUMBER AND unknown ***/!!!
         NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_) AS
         residual_value_,
         CASE
            WHEN (residual_value_=0 AND base_value_!=0)
               THEN 'TRUE'
            ELSE 'FALSE'
         END AS fully_depritiated_
   )
   SELECT
      fully_depritiated_
   FROM
      declaration_variables_cte1
$$;
Copy

Oracle

CREATE OR REPLACE FUNCTION Case2_1 (
   year_        IN NUMBER,
   id           IN NUMBER) 
   RETURN VARCHAR2
IS
   base_value_        NUMBER;
   fully_depritiated_ VARCHAR2(5);
   residual_value_    NUMBER;
   acc_depr_prev_     NUMBER;
   acc_depr_          NUMBER;
BEGIN

   base_value_     := FOO1(year_, id);
   acc_depr_       := FOO2(year_, id);
   acc_depr_prev_  := FOO3(year_, id);
   residual_value_ := NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_);

   IF (residual_value_=0 AND base_value_!=0) THEN
      fully_depritiated_ := 'TRUE';
   ELSE
      fully_depritiated_ := 'FALSE';
   END IF;

   fully_depritiated := fully_depritiated || ' CONCAT FOR TESTING';
   fully_depritiated := fully_depritiated || ' CONCAT FOR TESTING2';
   RETURN fully_depritiated_;
END Case2;
Copy

Snowflake

--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "FOO1", "FOO2", "FOO3" **
CREATE OR REPLACE FUNCTION Case2_1 (year_ NUMBER(38, 18), id NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "07/16/2025",  "domain": "no-domain-provided" }}'
AS
$$
   WITH declaration_variables_cte1 AS
   (
      SELECT
         FOO1(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO1' NODE ***/!!! AS

         base_value_,
         FOO2(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO2' NODE ***/!!! AS
         acc_depr_,
         FOO3(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO3' NODE ***/!!! AS
         acc_depr_prev_,
         !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '-' MAY NOT BEHAVE CORRECTLY BETWEEN NUMBER AND unknown ***/!!!
         NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_) AS
         residual_value_,
         CASE
            WHEN (residual_value_=0 AND base_value_!=0)
               THEN 'TRUE'
            ELSE 'FALSE'
         END AS fully_depritiated_,
         NVL(fully_depritiated :: STRING, '') || ' CONCAT FOR TESTING' AS

         fully_depritiated
   ),
   declaration_variables_cte2 AS
   (
      SELECT
         NVL(fully_depritiated :: STRING, '') || ' CONCAT FOR TESTING2' AS
         fully_depritiated,
         base_value_,
         acc_depr_,
         acc_depr_prev_,
         residual_value_
      FROM
         declaration_variables_cte1
   )
   SELECT
      fully_depritiated_
   FROM
      declaration_variables_cte2
$$;
Copy

Oracle

CREATE OR REPLACE FUNCTION Case2_1 (
   year_        IN NUMBER,
   id           IN NUMBER) 
   RETURN VARCHAR2
IS
   base_value_        NUMBER;
   fully_depritiated_ VARCHAR2(5);
   residual_value_    NUMBER;
   acc_depr_prev_     NUMBER;
   acc_depr_          NUMBER;
BEGIN

   base_value_     := FOO1(year_, id);
   acc_depr_       := FOO2(year_, id);
   acc_depr_prev_  := FOO3(year_, id);
   residual_value_ := NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_);

   IF (residual_value_=0 AND base_value_!=0) THEN
      fully_depritiated_ := 'TRUE';
   ELSE
      fully_depritiated_ := 'FALSE';
   END IF;

   fully_depritiated := fully_depritiated || ' CONCAT FOR TESTING';
   fully_depritiated := fully_depritiated || ' CONCAT FOR TESTING2';
   RETURN fully_depritiated_;
END Case2;
Copy

Snowflake

CREATE OR REPLACE FUNCTION Case2_1 (year_ NUMBER(38, 18), id NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "09/06/2024" }}'
AS
$$
   WITH declaration_variables_cte1 AS
   (
      SELECT
         FOO1(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO1' NODE ***/!!! AS

         base_value_,
         FOO2(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO2' NODE ***/!!! AS
         acc_depr_,
         FOO3(year_, id) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO3' NODE ***/!!! AS
         acc_depr_prev_,
         !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '-' MAY NOT BEHAVE CORRECTLY BETWEEN NUMBER AND unknown ***/!!!
         NVL(base_value_,0) -(acc_depr_ + acc_depr_prev_) AS
         residual_value_,
         CASE
            WHEN (residual_value_=0 AND base_value_!=0)
               THEN 'TRUE'
            ELSE 'FALSE'
         END AS fully_depritiated_,
         NVL(fully_depritiated :: STRING, '') || ' CONCAT FOR TESTING' AS

         fully_depritiated
   ),
   declaration_variables_cte2 AS
   (
      SELECT
         NVL(fully_depritiated :: STRING, '') || ' CONCAT FOR TESTING2' AS
         fully_depritiated,
         base_value_,
         acc_depr_,
         acc_depr_prev_,
         residual_value_
      FROM
         declaration_variables_cte1
   )
   SELECT
      fully_depritiated_
   FROM
      declaration_variables_cte2
$$;
Copy

Known Issues

문제가 발견되지 않았습니다.

관련 EWIS

  1. SSC-FDM-OR0042: 타임스탬프로 변환된 날짜 유형의 동작이 다릅니다.

  2. SSC-EWI-0073: 보류 중 함수 동등성 검토.

  3. SSC-EWI-OR0036: 유형 확인 문제로 인해 문자열과 날짜 사이에서 산술 연산이 올바르게 동작하지 않을 수 있습니다.

Snowflake 스크립트 UDF(SCALAR)

Oracle 사용자 정의 함수에서 [Snowflake Scripting UDFs]Snowflake Scripting UDFs로의 변환 참조

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

설명

이제 SnowConvert는 특정 기준을 충족하는 경우 Oracle PL/SQL 사용자 정의 함수에서 Snowflake Scripting UDFs(SnowScriptUDFs)로의 직접적인 변환을 지원합니다.

Snowflake Scripting UDFs는 SQL UDF 본문 내에서 Snowflake의 프로시저 언어 구문(Snowscript)을 사용하여 작성된 사용자 정의 함수입니다. 데이터베이스 액세스 없이 변수, 루프, 조건부 논리, 예외 처리를 지원합니다.

함수가 SnowScript UDFs가 되는 경우

SnowConvert는 각 Oracle 함수를 분석하고 적절한 Snowflake 대상을 자동으로 결정합니다. 함수는 데이터 액세스 작업 없이 프로시저 논리 포함하는 경우 SnowScript UDF가 됩니다.

샘플 소스 패턴

단순 계산 함수

데이터를 쿼리하지 않고 계산을 수행하는 기본 함수입니다.

Oracle
CREATE OR REPLACE FUNCTION CalculateTax (
    amount_ IN NUMBER,
    tax_rate_ IN NUMBER
) RETURN NUMBER
IS
    tax_amount_ NUMBER;
BEGIN
    tax_amount_ := amount_ * (tax_rate_ / 100);
    RETURN tax_amount_;
END CalculateTax;
Copy
결과

CALCULATETAX(1000, 15)

150

Snowflake(SnowScript UDF)
CREATE OR REPLACE FUNCTION CalculateTax (amount_ NUMBER(38, 18), tax_rate_ NUMBER(38, 18)
)
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "10/09/2025",  "domain": "no-domain-provided",  "migrationid": "zsqZAVE5n32hZZFtsi0zsg==" }}'
AS
$$
   DECLARE
      tax_amount_ NUMBER(38, 18);
   BEGIN
      tax_amount_ := :amount_ * (:tax_rate_ / 100);
      RETURN :tax_amount_;
   END;
$$;
Copy
결과

CALCULATETAX

150

IF/ELSIF/ELSE 논리가 있는 함수

비즈니스 논리에 조건문을 사용하는 함수입니다.

Oracle
CREATE OR REPLACE FUNCTION GetShippingCost (
    distance_ IN NUMBER,
    weight_ IN NUMBER
) RETURN NUMBER
IS
    shipping_cost_ NUMBER := 0;
BEGIN
    IF distance_ < 50 THEN
        shipping_cost_ := 10;
    ELSIF distance_ < 100 THEN
        shipping_cost_ := 20;
    ELSIF distance_ < 200 THEN
        shipping_cost_ := 35;
    ELSE
        shipping_cost_ := 50;
    END IF;
    
    IF weight_ > 20 THEN
        shipping_cost_ := shipping_cost_ * 1.5;
    END IF;
    
    RETURN shipping_cost_;
END GetShippingCost;
Copy
결과

GETSHIPPINGCOST(75, 25)

30

Snowflake(SnowScript UDF)
CREATE OR REPLACE FUNCTION GetShippingCost (distance_ NUMBER(38, 18), weight_ NUMBER(38, 18)
)
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "10/09/2025",  "domain": "no-domain-provided",  "migrationid": "zsqZAVE5n32hZZFtsi0zsg==" }}'
AS
$$
   DECLARE
      shipping_cost_ NUMBER(38, 18) := 0;
   BEGIN
      IF (:distance_ < 50) THEN
         shipping_cost_ := 10;
      ELSEIF (:distance_ < 100) THEN
         shipping_cost_ := 20;
      ELSEIF (:distance_ < 200) THEN
         shipping_cost_ := 35;
    ELSE
         shipping_cost_ := 50;
      END IF;
      IF (:weight_ > 20) THEN
         shipping_cost_ := :shipping_cost_ * 1.5;
      END IF;
      RETURN :shipping_cost_;
   END;
$$;
Copy
결과

GETSHIPPINGCOST

30

FOR Loop가 있는 함수

반복 계산을 위해 루프를 사용하는 함수입니다.

Oracle
CREATE OR REPLACE FUNCTION CalculateCompoundInterest (
    principal_ IN NUMBER,
    rate_ IN NUMBER,
    years_ IN NUMBER
) RETURN NUMBER
IS
    amount_ NUMBER;
    i NUMBER;
BEGIN
    amount_ := principal_;
    
    FOR i IN 1..years_ LOOP
        amount_ := amount_ * (1 + rate_ / 100);
    END LOOP;
    
    RETURN ROUND(amount_, 2);
END CalculateCompoundInterest;
Copy
결과

CALCULATECOMPOUNDINTEREST(1000, 5, 3)

1157.63

Snowflake(SnowScript UDF)
CREATE OR REPLACE FUNCTION CalculateCompoundInterest (principal_ NUMBER(38, 18), rate_ NUMBER(38, 18), years_ NUMBER(38, 18)
)
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "10/09/2025",  "domain": "no-domain-provided",  "migrationid": "zsqZAVE5n32hZZFtsi0zsg==" }}'
AS
$$
   DECLARE
      amount_ NUMBER(38, 18);
      i NUMBER(38, 18);
   BEGIN
      amount_ := :principal_;
      --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
      FOR i IN 1 TO :years_
                            --** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
                            LOOP
         amount_ := :amount_ * (
                                !!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '+' MAY NOT BEHAVE CORRECTLY BETWEEN Number AND unknown ***/!!!1 + :rate_ / 100);
                               END LOOP;
      RETURN ROUND(:amount_, 2);
   END;
$$;
Copy
결과

CALCULATECOMPOUNDINTEREST

1157.63

CASE 및 DECODE 논리

분류를 위해 CASE 식 및 DECODE를 사용하는 함수입니다.

Oracle
CREATE OR REPLACE FUNCTION GetCustomerTier (
    annual_spend_ IN NUMBER,
    years_active_ IN NUMBER
) RETURN VARCHAR2
IS
    tier_ VARCHAR2(20);
    base_tier_ VARCHAR2(20);
BEGIN
    -- Determine base tier by spending
    base_tier_ := CASE
        WHEN annual_spend_ >= 10000 THEN 'PLATINUM'
        WHEN annual_spend_ >= 5000 THEN 'GOLD'
        WHEN annual_spend_ >= 2000 THEN 'SILVER'
        ELSE 'BRONZE'
    END;
    
    -- Upgrade tier if customer is loyal (5+ years)
    IF years_active_ >= 5 THEN
        tier_ := DECODE(base_tier_,
            'GOLD', 'PLATINUM',
            'SILVER', 'GOLD',
            'BRONZE', 'SILVER',
            base_tier_);
    ELSE
        tier_ := base_tier_;
    END IF;
    
    RETURN tier_;
END GetCustomerTier;
Copy
결과

GETCUSTOMERTIER(3000, 6)

GOLD

Snowflake(SnowScript UDF)
CREATE OR REPLACE FUNCTION GetCustomerTier (annual_spend_ NUMBER(38, 18), years_active_ NUMBER(38, 18)
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "10/09/2025",  "domain": "no-domain-provided",  "migrationid": "zsqZAVE5n32hZZFtsi0zsg==" }}'
AS
$$
   DECLARE
      tier_ VARCHAR(20);
      base_tier_ VARCHAR(20);
   BEGIN
      -- Determine base tier by spending
      base_tier_ := CASE
                WHEN :annual_spend_ >= 10000 THEN 'PLATINUM'
                WHEN :annual_spend_ >= 5000 THEN 'GOLD'
                WHEN :annual_spend_ >= 2000 THEN 'SILVER'
                ELSE 'BRONZE'
            END;
      -- Upgrade tier if customer is loyal (5+ years)
      IF (:years_active_ >= 5) THEN
                tier_ := DECODE(:base_tier_,
                           'GOLD', 'PLATINUM',
                           'SILVER', 'GOLD',
                           'BRONZE', 'SILVER', :base_tier_);
      ELSE
                tier_ := :base_tier_;
      END IF;
      RETURN :tier_;
   END;
$$;
Copy
결과

GETCUSTOMERTIER

GOLD

Known Issues

경고

SnowScript UDFs는 다음을 수행할 수 없습니다.

  • 데이터베이스 테이블 액세스

  • 커서 사용

  • 기타 UDFs 호출

  • 집계 또는 윈도우 함수 포함

  • DML 작업(INSERT/UPDATE/DELETE) 수행

  • 결과 세트 반환

관련 EWIs

  1. SSC-EWI-0067: UDF가 Snowflake 프로시저로 변환되었으며, 쿼리 내에서 프로시저를 호출하는 기능은 지원되지 않습니다.

  2. SSC-EWI-0068: 사용자 정의 함수가 Snowflake 프로시저로 변환되었습니다.

  3. SSC-EWI-0073: 보류 중 함수 동등성 검토.

  4. SSC-FDM-OR0042: 타임스탬프로 변환된 날짜 유형의 동작이 다릅니다.