SnowConvert AI - Oracle - CREATE FUNCTION¶
OracleのSnowflake Snowスクリプトへの関数作成
説明¶
注釈
わかりやすくするため、出力コードの一部を省略しています。
ストアド関数 (ユーザー関数 または ユーザー定義関数 とも呼ばれます)は、名前で呼び出すことができる一連の PL/SQL ステートメントです。ストアド関数はプロシージャとよく似ていますが、関数は呼び出された環境に値を返すという点が異なります。ユーザー関数は、 SQL 式の一部として使用できます。
呼び出し仕様 は、Javaメソッドまたは第三世代言語(3GL)ルーチンを宣言し、 PL/SQL から呼び出せるようにします。このようなメソッドやルーチンを呼び出すには、
CALLSQL ステートメントを使用することもできます。呼び出し仕様は、呼び出しが行われたときにどの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 } } ;
Snowflake構文¶
Snowflakeでは、ユーザー定義関数で3つの異なる言語を使用できます。
SQL
JavaScript
Java
今のところ、 SnowConvert AI はターゲット言語として SQL と JavaScript のみをサポートします。
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>'
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>'
サンプルソースパターン¶
サンプル補助データ¶
注釈
このコードは例の理解を深めるために実行されました。
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'));
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'));
既知の問題¶
問題は見つかりませんでした。
return変数のカーソル¶
注釈
わかりやすくするため、出力コードの一部を省略しています。
このパターンは、Oracle PL/SQL で、カーソルを使用して単一の値をフェッチし、それを返す関数を定義します。
コンポーネント:
関数宣言:
CREATE FUNCTION functionName(parameters) RETURN returnType入力パラメーターと戻り値の型で関数を宣言します。
変数の宣言:
return変数を含む変数を宣言します。
カーソル宣言:
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];テーブルから1つの列を選択するためのカーソルを定義し、オプションのフィルター条件を指定します。
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;
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
$$;
結果¶
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;
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
$$;
結果¶
FUNC1() |
|---|
2004-05-03. |
既知の問題¶
問題は見つかりませんでした。
関連 EWIS¶
SSC-FDM-OR0042:日付型をタイムスタンプに変換すると異なる動作をします。
SSC-EWI-0073: 機能等価性レビュー保留中。
IF ステートメントを含むカーソル¶
注釈
わかりやすくするため、出力コードの一部を省略しています。
このパターンは、 IF ステートメントに基づいて、条件付きでカーソルを使用して値をフェッチして返す関数を定義します。
コンポーネント:
関数宣言:
CREATE FUNCTION functionName(parameters) RETURN returnType入力パラメーターと戻り値の型で関数を宣言します。
カーソル宣言:
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];テーブルから1つの列を選択するためのカーソルを定義し、オプションのフィルター条件を指定します。
変数宣言:
return変数を含む変数を宣言します。
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;
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
$$;
結果¶
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;
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
$$;
結果¶
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;
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
$$;
結果¶
FUNC2(0) |
|---|
0 |
FUNC2(1) |
|---|
33 |
既知の問題¶
問題は見つかりませんでした。
関連 EWIS¶
関連する EWIs なし。
複数の IFs ステートメント¶
このパターンは、ローカル変数に対する条件ステートメントを使用する関数を定義します。
コンポーネント:
関数宣言:
CREATE FUNCTION functionName(parameters) RETURN returnType入力パラメーターと戻り値の型で関数を宣言します。
変数宣言:
return変数を含む変数を宣言します。
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;
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
$$;
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;
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
$$;
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;
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
$$;
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;
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
$$;
既知の問題¶
問題は見つかりませんでした。
関連 EWIS¶
SSC-FDM-OR0042:日付型をタイムスタンプに変換すると異なる動作をします。
SSC-EWI-0073: 機能等価性レビュー保留中。
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;
結果¶
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;
$$;
結果¶
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;
結果¶
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;
$$;
結果¶
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;
結果¶
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;
$$;
結果¶
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;
結果¶
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;
$$;
結果¶
GETCUSTOMERTIER |
|---|
GOLD |
既知の問題¶
警告
** SnowScript UDFs は以下を行うことができません。**
データベーステーブルにアクセスする
カーソルを使用する
他の UDFs を呼び出す
集約またはウィンドウ関数を含む
DML 操作を実行する( INSERT/UPDATE/DELETE )
結果セットを返す
関連 EWIs¶
SSC-EWI-0067: UDF がSnowflakeプロシージャに変換されました。クエリ内でのプロシージャの呼び出しはサポートされていません。
SSC-EWI-0068:ユーザー定義関数がSnowflakeプロシージャに変換されました。
SSC-EWI-0073: 機能等価性レビュー保留中。
SSC-FDM-OR0042:日付型をタイムスタンプに変換すると異なる動作をします。