SnowConvert AI - Oracle - CREATE FUNCTION¶
Oracle Create Function vers Snowflake Snow Scripting
Description¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Une fonction stockée (également appelée fonction utilisateur ou fonction définie par l’utilisateur) est un ensemble d’instructions PL/SQL que vous pouvez appeler par leur nom. Les fonctions stockées sont très similaires aux procédures, à l’exception du fait qu’une fonction renvoie une valeur à l’environnement dans lequel elle est appelée. Les fonctions utilisateur peuvent être utilisées dans le cadre d’une expression SQL.
Une spécification d’appel déclare une méthode Java ou une routine en langue de troisième génération (3GL) afin qu’elle puisse être appelée à partir de PL/SQL. Vous pouvez également utiliser l’instruction
CALLSQL pour appeler une telle méthode ou routine. La spécification d’appel indique à la base de données Oracle quelle méthode Java, ou quelle fonction nommée dans quelle bibliothèque partagée, doit être invoquée lors d’un appel. Elle indique également à la base de données les conversions de type à effectuer pour les arguments et la valeur de retour. Référence linguistique Oracle SQL Create Function.
Syntaxe Oracle¶
Pour plus d’informations sur Oracle Create Function, cliquez ici.
Syntaxe de Create Function d’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 } } ;
Syntaxe Snowflake¶
Snowflake permet l’utilisation de 3 langues différentes dans les fonctions définies par l’utilisateur :
SQL
JavaScript
Java
Pour l’instant, SnowConvert AI prendra en charge uniquement SQL et JavaScript comme langues cibles.
Pour plus d’informations sur Snowflake Create Function, cliquez ici.
SQL¶
Note
Les fonctions SQL définies par l’utilisateur n’acceptent qu’une seule requête comme corps. Ils peuvent lire dans la base de données mais ne sont pas autorisés à y écrire ou à la modifier (UDFs SQL scalaires).
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¶
Note
Les fonctions définies par l’utilisateur JavaScript autorisent plusieurs instructions dans leur corps, mais ne peuvent pas effectuer de requêtes dans la base de données. (UDFs JavaScript scalaires).
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>'
Modèles d’échantillons de sources¶
Exemple de données auxiliaires¶
Note
Ce code a été exécuté pour une meilleure compréhension des exemples :
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'));
Problèmes connus¶
Aucun problème n’a été constaté.
Curseur pour une variable de retour¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Ce modèle définit une fonction dans Oracle PL/SQL qui utilise un curseur pour récupérer une valeur unique et la renvoyer.
Composants :
Déclaration de fonction :
CREATE FUNCTION functionName(parameters) RETURN returnTypeDéclare la fonction avec les paramètres d’entrée et le type de retour.
Déclarations de variables :
Déclare les variables, y compris la variable de retour.
Déclaration de curseurs :
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];Définit un curseur permettant de sélectionner une seule colonne dans une table avec des conditions de filtrage facultatives.
Bloc BEGIN-END :
Affectation des variables.
Ouvre le curseur.
Récupère le résultat dans la variable de retour.
Ferme le curseur.
Renvoie la valeur retournée.
Dans ce cas, les variables sont transformées en une expression de table commune (CTE). Ainsi que la requête dans le curseur à laquelle, en outre, la clause FETCH FIRST 1 ROW ONLY est ajoutée pour simuler le comportement de FETCH CURSOR.
L’instruction RETURN est transformée en sélection finale.
Requêtes¶
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
$$;
Résultat¶
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
$$;
Résultat¶
FUNC1() |
|---|
2004-05-03 |
Problèmes connus¶
Aucun problème n’a été constaté.
connexesEWIS¶
SSC-FDM-OR0042: Le type de date transformé en horodatage a un comportement différent.
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
Curseur avec instruction IF¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Ce modèle définit une fonction qui utilise conditionnellement un curseur pour rechercher et renvoyer une valeur en fonction d’une instruction IF.
Composants :
Déclaration de fonction :
CREATE FUNCTION functionName(parameters) RETURN returnTypeDéclare la fonction avec les paramètres d’entrée et le type de retour.
Déclaration de curseurs :
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];Définit un curseur permettant de sélectionner une seule colonne dans une table avec des conditions de filtrage facultatives.
Déclaration de variables :
Déclare les variables, y compris la variable de retour.
Bloc BEGIN-END avec instruction IF :
Affectation des variables.
Vérifier si une condition est vraie.
Si true, ouvre le curseur, récupère le résultat dans la variable de retour, ferme le curseur et renvoie la valeur récupérée. (Le curseur peut également être ouvert dans le bloc
ELSEet doit répondre aux mêmes conditions)Le bloc
ELSEest facultatif. S’il existe, il ne doit contenir qu’une seule instruction qui peut être une affectation ou une instructionRETURN.
Les variables sont transformées en une expression de table commune (CTE). Ainsi que la requête dans le curseur à laquelle, en outre, la clause FETCH FIRST 1 ROW ONLY est ajoutée pour simuler le comportement de FETCH CURSOR.
L'instruction IF/ELSE peut être traitée en utilisant CASE EXPRESSION à l’intérieur de la sélection, ce qui permet d’insérer des conditions dans les requêtes. L’instruction RETURN est transformée en sélection finale.
Requêtes¶
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
$$;
Résultat¶
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
$$;
Résultat¶
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
$$;
Résultat¶
FUNC2(0) |
|---|
0 |
FUNC2(1) |
|---|
33 |
Problèmes connus¶
Aucun problème n’a été constaté.
connexesEWIS¶
Pas d’EWIs connexes.
Instruction à plusieurs IFs¶
Ce modèle définit une fonction qui utilise des instructions conditionnelles sur des variables locales.
Composants :
Déclaration de fonction :
CREATE FUNCTION functionName(parameters) RETURN returnTypeDéclare la fonction avec les paramètres d’entrée et le type de retour.
Déclaration de variables :
Déclare les variables, y compris la variable de retour.
Bloc BEGIN-END avec instruction IF :
Vérifier si une condition est vraie.
Chaque cas est utilisée pour attribuer une valeur à la même variable.
Conversion :¶
DECLARE SECTION : les variables avec une expression par défaut sont déplacées vers une expression de table commune.
L'instruction IF/ELSE peut être traitée à l’aide de CASE EXPRESSION à l’intérieur de la sélection, ce qui permet d’introduire des conditions dans les requêtes.
L’instruction RETURN est transformée en sélection finale.
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
$$;
Problèmes connus¶
Aucun problème n’a été constaté.
connexesEWIS¶
SSC-FDM-OR0042: Le type de date transformé en horodatage a un comportement différent.
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-EWI-OR0036: Problèmes de résolution des types, l’opération arithmétique peut ne pas se comporter correctement entre la chaîne et la date.
UDF (SCALAR) Snowflake Scripting¶
Référence de traduction pour les fonctions définies par l’utilisateur Oracle vers [UDFsSnowflake Scripting] UDFs Snowflake Scripting
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
SnowConvert prend désormais en charge la traduction des fonctions définies par l’utilisateur PL/SQL Oracle directement en UDFs Snowflake Scripting (UDFs SnowScript) lorsqu’elles répondent à des critères spécifiques.
Les UDFs Snowflake Scripting sont des fonctions définies par l’utilisateur écrites à l’aide de la syntaxe du langage procédural de Snowflake (Snowscript) au sein d’un corps SQL UDF. Elles prennent en charge les variables, les boucles, la logique conditionnelle et la gestion des exceptions sans nécessiter d’accès à la base de données.
Lorsque les fonctions deviennent des SnowScript UDFs¶
SnowConvert analyse chaque fonction Oracle et détermine automatiquement la cible Snowflake appropriée. Une fonction devient une SnowScript UDF lorsqu’elle contient uniquement une logique procédurale sans opérations d’accès aux données.
Modèles d’échantillons de sources¶
Fonction de calcul simple¶
Une fonction de base qui effectue des calculs sans interroger de données.
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;
Résultat¶
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;
$$;
Résultat¶
CALCULATETAX |
|---|
150 |
Fonction avec la logique IF/ELSIF/ELSE¶
Fonctions utilisant des instructions conditionnelles pour la logique métier.
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;
Résultat¶
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;
$$;
Résultat¶
GETSHIPPINGCOST |
|---|
30 |
Fonction avec FOR Loop¶
Fonctions utilisant des boucles pour les calculs itératifs.
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;
Résultat¶
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;
$$;
Résultat¶
CALCULATECOMPOUNDINTEREST |
|---|
1157.63 |
Logique CASE et DECODE¶
Fonctions utilisant des expressions CASE et DECODE pour la catégorisation.
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;
Résultat¶
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;
$$;
Résultat¶
GETCUSTOMERTIER |
|---|
GOLD |
Problèmes connus¶
Avertissement
Les SnowScript UDFs ne peuvent pas :
Accès aux tables de la base de données
Utiliser des curseurs
Appeler d’autres UDFs
Fonctions d’agrégation ou de fenêtre,
Exécuter des opérations DML (INSERT/UPDATE/DELETE)
Renvoyer les jeux de résultats
EWIs connexes¶
SSC-EWI-0067: UDF was transformed to Snowflake procedure, calling procedures inside a query is not supported.
SSC-EWI-0068: La fonction définie par l’utilisateur a été transformée en procédure Snowflake.
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-FDM-OR0042: Le type de date transformé en horodatage a un comportement différent.