SnowConvert AI - Oracle - CREATE FUNCTION

OracleのSnowflake Snowスクリプトへの関数作成

説明

注釈

わかりやすくするため、出力コードの一部を省略しています。

ストアド関数ユーザー関数 または ユーザー定義関数 とも呼ばれます)は、名前で呼び出すことができる一連の PL/SQL ステートメントです。ストアド関数はプロシージャとよく似ていますが、関数は呼び出された環境に値を返すという点が異なります。ユーザー関数は、 SQL 式の一部として使用できます。

呼び出し仕様 は、Javaメソッドまたは第三世代言語(3GL)ルーチンを宣言し、 PL/SQL から呼び出せるようにします。このようなメソッドやルーチンを呼び出すには、 CALL SQL ステートメントを使用することもできます。呼び出し仕様は、呼び出しが行われたときにどのJavaメソッド、またはどの共有ライブラリ内のどの名前付き関数を呼び出すかをOracleデータベースに伝えます。また、引数と戻り値の型変換もデータベースに指示します。Oracle SQL 言語リファレンス関数の作成

Oracle構文

Oracleの関数作成の詳細情報については、 こちら をご覧ください。

Oracleの関数作成の構文

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の関数作成の詳細情報については、 こちら をご覧ください。

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

既知の問題

問題は見つかりませんでした。

return変数のカーソル

注釈

わかりやすくするため、出力コードの一部を省略しています。

このパターンは、Oracle PL/SQL で、カーソルを使用して単一の値をフェッチし、それを返す関数を定義します。

コンポーネント:

  1. 関数宣言:

    • CREATE FUNCTION functionName(parameters) RETURN returnType

    • 入力パラメーターと戻り値の型で関数を宣言します。

  2. 変数の宣言:

    • return変数を含む変数を宣言します。

  3. カーソル宣言:

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

    • テーブルから1つの列を選択するためのカーソルを定義し、オプションのフィルター条件を指定します。

  4. BEGIN-END ブロック:

    • 変数の割り当て。

    • カーソルを開きます。

    • 結果をreturn変数に取得します。

    • カーソルを閉じます。

    • 取得した値を返します。

この場合、変数は共通テーブル式(CTE)に変換されます。カーソル内のクエリと同様に、 FETCH CURSOR の動作をシミュレートするために、 FETCH FIRST 1 ROW ONLY 句が追加されています。

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.

既知の問題

問題は見つかりませんでした。

関連 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];

    • テーブルから1つの列を選択するためのカーソルを定義し、オプションのフィルター条件を指定します。

  3. 変数宣言:

    • return変数を含む変数を宣言します。

  4. IF ステートメントを含む BEGIN-END ブロック:

    • 変数の割り当て。

    • 条件がtrueかどうかをチェックします。

    • trueの場合、カーソルを開き、return変数に結果をフェッチし、カーソルを閉じ、フェッチされた値を返します。(カーソルは ELSE ブロックでも開くことができ、同じ条件を満たす必要があります)

    • ELSE ブロックはオプションです。存在する場合は、割り当てまたは RETURN ステートメントになる単一のステートメントのみを含める必要があります。

変数は共通テーブル式(CTE)に変換されます。カーソル内のクエリと同様に、 FETCH CURSOR の動作をシミュレートするために、 FETCH FIRST 1 ROW ONLY 句が追加されています。

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

既知の問題

問題は見つかりませんでした。

関連 EWIS

関連する EWIs なし。

複数の IFs ステートメント

このパターンは、ローカル変数に対する条件ステートメントを使用する関数を定義します。

コンポーネント:

  1. 関数宣言:

    • CREATE FUNCTION functionName(parameters) RETURN returnType

    • 入力パラメーターと戻り値の型で関数を宣言します。

  2. 変数宣言:

    • return変数を含む変数を宣言します。

  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

既知の問題

問題は見つかりませんでした。

関連 EWIS

  1. SSC-FDM-OR0042:日付型をタイムスタンプに変換すると異なる動作をします。

  2. SSC-EWI-0073: 機能等価性レビュー保留中。

  3. SSC-EWI-OR0036:型解決の問題で、文字列と日付の間の算術演算が正しく動作しないことがあります。

Snowflakeスクリプト UDF ( SCALAR )

Oracleのユーザー定義関数から [Snowflakeスクリプト UDFs]Snowflakeスクリプト UDFs への翻訳リファレンス

注釈

わかりやすくするため、出力コードの一部を省略しています。

説明

SnowConvert は、Oracle PL/SQL ユーザー定義関数が特定の条件を満たす場合、 **Snowflakeスクリプト UDFs ** ( SnowScript UDFs )への直接の翻訳をサポートするようになりました。

**Snowflakeスクリプト UDFs **は、Snowflakeのプロシージャ言語構文(Snowscript)を使用して、 SQL UDF 本文内に記述されるユーザー定義関数です。データベースへのアクセスを必要とせず、変数、ループ、条件付きロジック、例外処理をサポートしています。

関数が 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 ループを持つ関数

反復計算にループを使用する関数。

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

既知の問題

警告

** 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:日付型をタイムスタンプに変換すると異なる動作をします。