SnowConvert AI - Oracle - PL/SQL vers Snowflake Scripting¶
ASSIGNMENT STATEMENT¶
Description¶
L’instruction d’affectation de définit la valeur d’un élément de données sur une valeur valide.\ (Référence linguistique Oracle PL/SQL Instruction ASSIGNMENT).
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Syntaxe d’affectation Oracle¶
assignment_statement_target := expression ;
assignment_statement_target =
{ collection_variable [ ( index ) ]
| cursor_variable
| :host_cursor_variable
| object[.attribute]
| out_parameter
| placeholder
| record_variable[.field]
| scalar_variable
}
Syntaxe d’affectation de Snowflake Scripting¶
LET <variable_name> <type> { DEFAULT | := } <expression> ;
LET <variable_name> { DEFAULT | := } <expression> ;
Note
Le mot-clé LET n’est pas nécessaire pour les instructions d’affectation lorsque la variable a été déclarée auparavant. Consultez la documentation sur l’affectation Snowflake pour plus d’informations.
Modèles d’échantillons de sources¶
1. Scalar Variables¶
Oracle¶
CREATE TABLE TASSIGN (
COL1 NUMBER,
COL2 NUMBER,
COL3 VARCHAR(20),
COL4 VARCHAR(20)
);
CREATE OR REPLACE PROCEDURE PSCALAR
AS
var1 NUMBER := 40;
var2 NUMBER := 22.50;
var3 VARCHAR(20);
var4 BOOLEAN;
var5 NUMBER;
BEGIN
var1 := 1;
var2 := 2.1;
var2 := var2 + var2;
var3 := 'Hello World';
var4 := true;
var4 := var1 > 500;
IF var4 THEN
var5 := 0;
ELSE
var5 := 1;
END IF;
INSERT INTO TASSIGN VALUES(var1, var2, var3, var5);
END;
CALL PSCALAR();
SELECT * FROM TASSIGN;
Résultat¶
COL1 |
COL2 |
COL3 |
COL4 |
|---|---|---|---|
1 |
4.2 |
Bonjour le monde |
1 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE TASSIGN (
COL1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
COL2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
COL3 VARCHAR(20),
COL4 VARCHAR(20)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE PSCALAR ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
var1 NUMBER(38, 18) := 40;
var2 NUMBER(38, 18) := 22.50;
var3 VARCHAR(20);
var4 BOOLEAN;
var5 NUMBER(38, 18);
BEGIN
var1 := 1;
var2 := 2.1;
var2 := :var2 + :var2;
var3 := 'Hello World';
var4 := true;
var4 := :var1 > 500;
IF (:var4) THEN
var5 := 0;
ELSE
var5 := 1;
END IF;
INSERT INTO TASSIGN
VALUES(:var1, :var2, :var3, :var5);
END;
$$;
CALL PSCALAR();
SELECT * FROM
TASSIGN;
Résultat¶
COL1 |
COL2 |
COL3 |
COL4 |
|---|---|---|---|
1.000000000000000000 |
4.000000000000000000 |
Bonjour le monde |
1 |
Avertissement
La transformation de certains types de données doit être mise à jour, ce qui peut entraîner des résultats différents. Par exemple, NUMBER à NUMBER arrondit la valeur et le point décimal est perdu. Cette question fait déjà l’objet d’un document de travail.
2. Out Parameter Assignment¶
Pour obtenir plus d’informations sur la conversion des paramètres de sortie, veuillez consulter l’article suivant Paramètres de sortie.
3. Not Supported Assignments¶
Oracle¶
CREATE OR REPLACE PROCEDURE pinvalid(out_parameter IN OUT NUMBER)
AS
record_variable employees%ROWTYPE;
TYPE cursor_type IS REF CURSOR;
cursor1 cursor_type;
cursor2 SYS_REFCURSOR;
TYPE collection_type IS TABLE OF NUMBER INDEX BY VARCHAR(64);
collection_variable collection_type;
BEGIN
--Record Example
record_variable.last_name := 'Ortiz';
--Cursor Example
cursor1 := cursor2;
--Collection
collection_variable('Test') := 5;
--Out Parameter
out_parameter := 123;
END;
Exécution de scripts Snowflake¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "employees" **
CREATE OR REPLACE PROCEDURE pinvalid (out_parameter OUT 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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
record_variable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWTYPE DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL REF CURSOR TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- TYPE cursor_type IS REF CURSOR;
cursor1_res RESULTSET;
cursor2_res RESULTSET;
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- TYPE collection_type IS TABLE OF NUMBER INDEX BY VARCHAR(64);
collection_variable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'collection_type' USAGE CHANGED TO VARIANT ***/!!!;
BEGIN
--Record Example
record_variable := OBJECT_INSERT(record_variable, 'LAST_NAME', 'Ortiz', true);
--Cursor Example
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0108 - THE FOLLOWING ASSIGNMENT STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
cursor1 := :cursor2;
--Collection
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0108 - THE FOLLOWING ASSIGNMENT STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
collection_variable('Test') := 5;
--Out Parameter
out_parameter := 123;
END;
$$;
Problèmes connus¶
1. Several Unsupported Assignment Statements¶
Actuellement, la transformation des variables de type curseur, collection, enregistrement et définies par l’utilisateur n’est pas prise en charge par Snow Scripting. Par conséquent, les instructions d’affectation utilisant ces variables sont commentées et marquées comme n’étant pas prises en charge. Le remplacement de ces variables par des types de données semi-structurées Snowflake pourrait constituer une solution de contournement dans certains scénarios.
CALL¶
Description¶
Il existe deux types d’instructions d’appel dans Oracle :
1-Instruction CALL :¶
Utilisez l’instruction
CALLpour exécuter une routine (une procédure ou une fonction autonome, ou une procédure ou une fonction définie dans un type ou un paquet) à partir de SQL. (Référence linguistique Oracle SQL CALL)
2-Spécification d’appel .¶
Une spécification d’appel déclare une méthode Java ou un sous-programme en langue C de sorte qu’il puisse être invoqué à partir de PL/SQL. (Référence linguistique Oracle SQL Spécification d’appel)
La spécification CALL n’est pas prise en charge par le Snowflake Scripting car elle fait partie des bibliothèques de développement pour C et JAVA, et n’est pas une instruction SQL. Cette instruction n’est donc pas transformée.
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
Pas d’EWIs connexes.
CASE¶
Référence de traduction pour les instructions CASE
Description¶
L’instruction
CASEchoisit une séquence de conditions et exécute l’instruction correspondante. Pour plus d’informations sur Oracle CASE, cliquez ici.
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Cas simple¶
Syntaxe CASE Oracle¶
[ <<label>> ] CASE case_operand
WHEN boolean_expression THEN statement ;
[ WHEN boolean_expression THEN statement ; ]...
[ ELSE statement [ statement ]... ;
END CASE [ label ] ;
Syntaxe CASE Snowflake Scripting¶
CASE ( <expression_to_match> )
WHEN <expression> THEN
<statement>;
[ <statement>; ... ]
[ WHEN ... ]
[ ELSE
<statement>;
[ <statement>; ... ]
]
END [ CASE ] ;
Cas recherché¶
Syntaxe CASE Oracle¶
[ <<label>> ] CASE
WHEN boolean_expression THEN statement ;
[ WHEN boolean_expression THEN statement ; ]...
[ ELSE statement [ statement ]... ;
END CASE [ label ];
Syntaxe CASE Snowflake Scripting¶
CASE
WHEN <boolean_expression> THEN
<statement>;
[ <statement>; ... ]
[ WHEN ... ]
[ ELSE
<statement>;
[ <statement>; ... ]
]
END [ CASE ] ;
Modèles d’échantillons de sources¶
Échantillon de table auxiliaire¶
Oracle¶
CREATE TABLE case_table(col varchar(30));
Snowflake¶
CREATE OR REPLACE TABLE case_table (col varchar(30))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Cas simple¶
Oracle¶
CREATE OR REPLACE PROCEDURE caseExample1 ( grade NUMBER )
IS
RESULT VARCHAR(20);
BEGIN
<<CASE1>>
CASE grade
WHEN 10 THEN RESULT:='Excellent';
WHEN 9 THEN RESULT:='Very Good';
WHEN 8 THEN RESULT:='Good';
WHEN 7 THEN RESULT:='Fair';
WHEN 6 THEN RESULT:='Poor';
ELSE RESULT:='No such grade';
END CASE CASE1;
INSERT INTO CASE_TABLE(COL) VALUES (RESULT);
END;
CALL caseExample1(6);
CALL caseExample1(4);
CALL caseExample1(10);
SELECT * FROM CASE_TABLE;
Résultat¶
COL |
|---|
Mauvaise |
Pas de telle classification |
Excellent |
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE caseExample1 (grade NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
RESULT VARCHAR(20);
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<CASE1>> ***/!!!
CASE :grade
WHEN 10 THEN
RESULT := 'Excellent';
WHEN 9 THEN
RESULT := 'Very Good';
WHEN 8 THEN
RESULT := 'Good';
WHEN 7 THEN
RESULT := 'Fair';
WHEN 6 THEN
RESULT := 'Poor';
ELSE
RESULT := 'No such grade';
END CASE;
INSERT INTO CASE_TABLE(COL) VALUES (:RESULT);
END;
$$;
CALL caseExample1(6);
CALL caseExample1(4);
CALL caseExample1(10);
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "CASE_TABLE" **
SELECT * FROM
CASE_TABLE;
Résultat¶
COL |
|---|
Mauvaise |
Pas de telle classification |
Excellent |
Cas recherché¶
Oracle¶
CREATE OR REPLACE PROCEDURE caseExample2 ( grade NUMBER )
IS
RESULT VARCHAR(20);
BEGIN
<<CASE1>>
CASE
WHEN grade = 10 THEN RESULT:='Excellent';
WHEN grade = 9 THEN RESULT:='Very Good';
WHEN grade = 8 THEN RESULT:='Good';
WHEN grade = 7 THEN RESULT:='Fair';
WHEN grade = 6 THEN RESULT:='Poor';
ELSE RESULT:='No such grade';
END CASE CASE1;
INSERT INTO CASE_TABLE(COL) VALUES (RESULT);
END;
CALL caseExample2(6);
CALL caseExample2(4);
CALL caseExample2(10);
SELECT * FROM CASE_TABLE;
Résultat¶
COL |
|---|
Mauvaise |
Pas de telle classification |
Excellent |
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE caseExample2 (grade NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
RESULT VARCHAR(20);
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<CASE1>> ***/!!!
CASE
WHEN :grade = 10 THEN
RESULT := 'Excellent';
WHEN :grade = 9 THEN
RESULT := 'Very Good';
WHEN :grade = 8 THEN
RESULT := 'Good';
WHEN :grade = 7 THEN
RESULT := 'Fair';
WHEN :grade = 6 THEN
RESULT := 'Poor';
ELSE
RESULT := 'No such grade';
END CASE;
INSERT INTO CASE_TABLE(COL) VALUES (:RESULT);
END;
$$;
CALL caseExample2(6);
CALL caseExample2(4);
CALL caseExample2(10);
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "CASE_TABLE" **
SELECT * FROM
CASE_TABLE;
Résultat¶
COL |
|---|
Mauvaise |
Pas de telle classification |
Excellent |
Problèmes connus¶
1. Labels are not supported in Snowflake Scripting CASE syntax¶
Les étiquettes sont commentées ou supprimées en fonction de leur position.
connexesEWIS¶
SSC-EWI-0094: La déclaration des étiquettes n’est pas prise en charge.
SSC-FDM-0007: Élément avec des dépendances manquantes.
COMPOUND STATEMENTS¶
Cette section est une spécification de traduction pour les instructions composées.
Avertissement
Les informations de cette section, en cours de modification, sont sujettes à modification.
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description générale¶
L’unité de base d’un programme source PL/SQL est le bloc, qui regroupe les déclarations et instructions connexes.
Un bloc PL/SQL est défini par les mots-clés DECLARE, BEGIN, EXCEPTION et END. Ces mots-clés divisent le bloc en une partie déclarative, une partie exécutable et une partie de traitement des exceptions. Seule la partie exécutable est exigée. (Blocs anonymes PL/SQL)
Le bloc BEGIN...END dans Oracle peut présenter les caractéristiques suivantes :
Être imbriqué.
Contenir l’instruction DECLARE pour les variables.
Grouper plusieurs instructions SQL ou PL/SQL.
Syntaxe Oracle¶
[DECLARE <Variable declaration>]
BEGIN
<Executable statements>
[EXCEPTION <Exception handler>]
END
Syntaxe Snowflake¶
BEGIN
<statement>;
[ <statement>; ... ]
[ EXCEPTION <exception_handler> ]
END;
Note
Dans Snowflake, un bloc BEGIN/END peut être la construction de premier niveau à l’intérieur d’un bloc anonyme (documentation de Snowflake).
Modèles d’échantillons de sources¶
1. IF-ELSE block¶
Consultez la documentation suivante sur les instructions IF pour en savoir plus : traduction des instructions SnowConvert AI IF et documentation de l’instruction Snowflake IF
Oracle¶
DECLARE
age NUMBER := 18;
BEGIN
IF age >= 18 THEN
DBMS_OUTPUT.PUT_LINE('You are an adult.');
ELSE
DBMS_OUTPUT.PUT_LINE('You are a minor.');
END IF;
END;
Résultat¶
Statement processed.
You are an adult.
Snowflake¶
Avertissement
Lors de l’appel d’une procédure ou d’une fonction définie par l’utilisateur (UDF), il est nécessaire de générer du code pour prendre en charge l’équivalence avec la variable call_results. Dans ce cas, sert à imprimer l’information.
Examinez la fonction définie par l’utilisateur (UDF) utilisée ici.
DECLARE
age NUMBER(38, 18) := 18;
call_results VARIANT;
BEGIN
IF (:age >= 18) THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('You are an adult.')
);
ELSE
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('You are a minor.')
);
END IF;
RETURN call_results;
END;
Résultat¶
anonymous block
You are an adult.
2. CASE statement¶
Pour plus d’informations, consultez la documentation suivante : documentation de l’instruction SnowConvert AI CASE et Documentation CASE Snowflake
Oracle¶
BEGIN
DECLARE
day_of_week NUMBER := 3;
BEGIN
CASE day_of_week
WHEN 1 THEN DBMS_OUTPUT.PUT_LINE('Sunday');
WHEN 2 THEN DBMS_OUTPUT.PUT_LINE('Monday');
WHEN 3 THEN DBMS_OUTPUT.PUT_LINE('Tuesday');
WHEN 4 THEN DBMS_OUTPUT.PUT_LINE('Wednesday');
WHEN 5 THEN DBMS_OUTPUT.PUT_LINE('Thursday');
WHEN 6 THEN DBMS_OUTPUT.PUT_LINE('Friday');
WHEN 7 THEN DBMS_OUTPUT.PUT_LINE('Saturday');
ELSE DBMS_OUTPUT.PUT_LINE('Invalid day');
END CASE;
END;
END;
Résultat¶
Statement processed.
Tuesday
Snowflake¶
Avertissement
Lors de l’appel d’une procédure ou d’une fonction définie par l’utilisateur (UDF), il est nécessaire de générer du code pour prendre en charge l’équivalence avec la variable call_results. Dans ce cas, sert à imprimer l’information.
Examinez la fonction définie par l’utilisateur (UDF) utilisée ici.
DECLARE
call_results VARIANT;
BEGIN
DECLARE
day_of_week NUMBER(38, 18) := 3;
BEGIN
CASE :day_of_week
WHEN 1 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Sunday')
);
WHEN 2 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Monday')
);
WHEN 3 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Tuesday')
);
WHEN 4 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Wednesday')
);
WHEN 5 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Thursday')
);
WHEN 6 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Friday')
);
WHEN 7 THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Saturday')
);
ELSE
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('Invalid day')
);
END CASE;
END;
RETURN call_results;
END;
Résultat¶
anonymous block
Tuesday
3. LOOP statements¶
Pour plus d’informations, consultez la documentation suivante : SnowConvert AI FOR LOOP et la [documentation LOOP] Snowflake (https://docs.snowflake.com/en/sql-reference/snowflake-scripting/loop) et la documentation FOR.
Oracle¶
BEGIN
FOR i IN 1..10 LOOP
NULL;
END LOOP;
END;
Résultat¶
Statement processed.
Snowflake¶
Premier onglet¶
BEGIN
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN 1 TO 10
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
END;
Résultat¶
anonymous block
4. Procedure call and OUTPUT parameters¶
Le bloc anonyme dans Oracle peut avoir des appels à des procédures. En outre, la documentation suivante peut être utile : documentation de la procédureSnowConvert AI.
L’exemple suivant utilise les paramètres OUT. Vous trouverez les informations sur la transformation actuelle ici : Paramètres SnowConvert AI OUTPUT
Oracle¶
-- Procedure declaration
CREATE OR REPLACE PROCEDURE calculate_sum(
p_num1 IN NUMBER,
p_num2 IN NUMBER,
p_result OUT NUMBER
)
IS
BEGIN
-- Calculate the sum of the two numbers
p_result := p_num1 + p_num2;
END;
/
-- Anonymous block with a procedure call
DECLARE
-- Declare variables to hold the input and output values
v_num1 NUMBER := 10;
v_num2 NUMBER := 20;
v_result NUMBER;
BEGIN
-- Call the procedure with the input values and get the result
calculate_sum(v_num1, v_num2, v_result);
-- Display the result
DBMS_OUTPUT.PUT_LINE('The sum of ' || v_num1 || ' and ' || v_num2 || ' is ' || v_result);
END;
/
Résultat¶
Statement processed.
The sum of 10 and 20 is 30
Snowflake¶
-- Procedure declaration
CREATE OR REPLACE PROCEDURE calculate_sum (p_num1 NUMBER(38, 18), p_num2 NUMBER(38, 18), p_result OUT 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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
-- Calculate the sum of the two numbers
p_result := :p_num1 + :p_num2;
END;
$$;
-- Anonymous block with a procedure call
DECLARE
-- Declare variables to hold the input and output values
v_num1 NUMBER(38, 18) := 10;
v_num2 NUMBER(38, 18) := 20;
v_result NUMBER(38, 18);
call_results VARIANT;
BEGIN
CALL
-- Call the procedure with the input values and get the result
calculate_sum(:v_num1, :v_num2, :v_result);
-- Display the result
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF('The sum of ' || NVL(:v_num1 :: STRING, '') || ' and ' || NVL(:v_num2 :: STRING, '') || ' is ' || NVL(:v_result :: STRING, ''))
);
RETURN call_results;
END;
Résultat¶
anonymous block
The sum of 10 and 20 is 30
5. Alter session¶
Pour plus d’informations, consultez la documentation suivante : documentation Modifier la session.
Remarquez que dans Oracle, le bloc BEGIN...END doit utiliser l’instruction EXECUTE IMMEDIATE pour exécuter les instructions alter session.
Oracle¶
DECLARE
lv_sql_txt VARCHAR2(200);
BEGIN
lv_sql_txt := 'ALTER SESSION SET nls_date_format = ''DD-MM-YYYY''';
EXECUTE IMMEDIATE lv_sql_txt;
END;
Résultat¶
Statement processed.
Done
Snowflake¶
DECLARE
lv_sql_txt VARCHAR(200);
BEGIN
lv_sql_txt := 'ALTER SESSION SET nls_date_format = ''DD-MM-YYYY''';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!!!!RESOLVE EWI!!! /*** SSC-EWI-0027 - THE FOLLOWING STATEMENT USES A VARIABLE/LITERAL WITH AN INVALID QUERY AND IT WILL NOT BE EXECUTED ***/!!!
EXECUTE IMMEDIATE :lv_sql_txt;
END;
Résultat¶
anonymous block
Done
6. Cursors¶
L’exemple suivant montre l’utilisation d’un curseur à l’intérieur d’un bloc BEGIN...END. Consultez la documentation suivante pour en savoir plus : documentation sur les curseurs.
Oracle¶
CREATE TABLE employee (
ID_Number NUMBER,
emp_Name VARCHAR(200),
emp_Phone NUMBER
);
INSERT INTO employee VALUES (1, 'NameA NameZ', 1234567890);
INSERT INTO employee VALUES (2, 'NameB NameY', 1234567890);
DECLARE
var1 VARCHAR(20);
CURSOR cursor1 IS SELECT emp_Name FROM employee ORDER BY ID_Number;
BEGIN
OPEN cursor1;
FETCH cursor1 INTO var1;
CLOSE cursor1;
DBMS_OUTPUT.PUT_LINE(var1);
END;
Résultat¶
Statement processed.
NameA NameZ
Snowflake¶
Avertissement
Lors de l’appel d’une procédure ou d’une fonction définie par l’utilisateur (UDF), il est nécessaire de générer du code pour prendre en charge l’équivalence avec la variable call_results. Dans ce cas, sert à imprimer l’information.
Examinez la fonction définie par l’utilisateur (UDF) utilisée ici.
CREATE OR REPLACE TABLE employee (
ID_Number NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
emp_Name VARCHAR(200),
emp_Phone NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
INSERT INTO employee
VALUES (1, 'NameA NameZ', 1234567890);
INSERT INTO employee
VALUES (2, 'NameB NameY', 1234567890);
DECLARE
var1 VARCHAR(20);
--** SSC-PRF-0009 - PERFORMANCE REVIEW - CURSOR USAGE **
cursor1 CURSOR
FOR
SELECT emp_Name FROM
employee
ORDER BY ID_Number;
call_results VARIANT;
BEGIN
OPEN cursor1;
FETCH cursor1 INTO
:var1;
CLOSE cursor1;
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF(:var1)
);
RETURN call_results;
END;
Résultat¶
anonymous block
NameA NameZ
7. Select statements¶
Pour plus d’informations, consultez la documentation suivante : documentation Sélection.
Oracle¶
CREATE TABLE employee (
ID_Number NUMBER,
emp_Name VARCHAR(200),
emp_Phone NUMBER
);
INSERT INTO employee VALUES (1, 'NameA NameZ', 1234567890);
INSERT INTO employee VALUES (2, 'NameB NameY', 1234567890);
DECLARE
var_Result NUMBER;
BEGIN
SELECT COUNT(*) INTO var_Result FROM employee;
DBMS_OUTPUT.PUT_LINE(var_Result);
END;
Résultat¶
Statement processed.
2
Snowflake¶
Avertissement
Lors de l’appel d’une procédure ou d’une fonction définie par l’utilisateur (UDF), il est nécessaire de générer du code pour prendre en charge l’équivalence avec la variable call_results. Dans ce cas, sert à imprimer l’information.
Examinez la fonction définie par l’utilisateur (UDF) utilisée ici.
CREATE OR REPLACE TABLE employee (
ID_Number NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
emp_Name VARCHAR(200),
emp_Phone NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
INSERT INTO employee
VALUES (1, 'NameA NameZ', 1234567890);
INSERT INTO employee
VALUES (2, 'NameB NameY', 1234567890);
DECLARE
var_Result NUMBER(38, 18);
call_results VARIANT;
BEGIN
SELECT COUNT(*) INTO
:var_Result
FROM
employee;
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF(:var_Result)
);
RETURN call_results;
END;
Résultat¶
anonymous block
2
8. Join Statements¶
Pour plus d’informations, consultez la documentation suivante : documentation Jointures.
Oracle¶
CREATE TABLE t1 (col1 INTEGER);
CREATE TABLE t2 (col1 INTEGER);
INSERT INTO t1 (col1) VALUES (2);
INSERT INTO t1 (col1) VALUES (3);
INSERT INTO t1 (col1) VALUES (4);
INSERT INTO t2 (col1) VALUES (1);
INSERT INTO t2 (col1) VALUES (2);
INSERT INTO t2 (col1) VALUES (2);
INSERT INTO t2 (col1) VALUES (3);
DECLARE
total_price FLOAT;
CURSOR cursor1 IS SELECT t1.col1 as FirstTable, t2.col1 as SecondTable
FROM t1 INNER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
BEGIN
total_price := 0.0;
FOR rec IN cursor1 LOOP
total_price := total_price + rec.FirstTable;
END LOOP;
DBMS_OUTPUT.PUT_LINE(total_price);
END;
Résultat¶
Statement processed.
7
Snowflake¶
Avertissement
Lors de l’appel d’une procédure ou d’une fonction définie par l’utilisateur (UDF), il est nécessaire de générer du code pour prendre en charge l’équivalence avec la variable call_results. Dans ce cas, sert à imprimer l’information.
Examinez la fonction définie par l’utilisateur (UDF) utilisée ici.
CREATE OR REPLACE TABLE t1 (col1 INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE TABLE t2 (col1 INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
INSERT INTO t1(col1) VALUES (2);
INSERT INTO t1(col1) VALUES (3);
INSERT INTO t1(col1) VALUES (4);
INSERT INTO t2(col1) VALUES (1);
INSERT INTO t2(col1) VALUES (2);
INSERT INTO t2(col1) VALUES (2);
INSERT INTO t2(col1) VALUES (3);
DECLARE
total_price FLOAT;
--** SSC-PRF-0009 - PERFORMANCE REVIEW - CURSOR USAGE **
cursor1 CURSOR
FOR
SELECT t1.col1 as FIRSTTABLE, t2.col1 as SECONDTABLE
FROM
t1
INNER JOIN
t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
call_results VARIANT;
BEGIN
total_price := 0.0;
OPEN cursor1;
--** SSC-PRF-0004 - THIS STATEMENT HAS USAGES OF CURSOR FOR LOOP **
FOR rec IN cursor1 DO
total_price :=
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0036 - TYPES RESOLUTION ISSUES, ARITHMETIC OPERATION '+' MAY NOT BEHAVE CORRECTLY BETWEEN FLOAT AND unknown ***/!!!
:total_price + rec.FIRSTTABLE;
END FOR;
CLOSE cursor1;
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
call_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF(:total_price)
);
RETURN call_results;
END;
9. Exception handling¶
Oracle¶
DECLARE
v_result NUMBER;
BEGIN
v_result := 1 / 0;
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE( SQLERRM );
END;
Résultat¶
Statement processed.
ORA-01476: divisor is equal to zero
Snowflake¶
Avertissement
L’exception ZERO_DIVIDE dans Snowflake n’est pas prise en charge.
DECLARE
v_result NUMBER(38, 18);
error_results VARIANT;
BEGIN
v_result := 1 / 0;
EXCEPTION
WHEN ZERO_DIVIDE THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
error_results := (
CALL DBMS_OUTPUT.PUT_LINE_UDF( SQLERRM )
);
RETURN error_results;
END;
Résultat¶
anonymous block
Division by zero
Problèmes connus¶
Instructions GOTO non prises en charge dans Oracle.
Les exceptions qui utilisent les instructions GOTO peuvent également être affectées.
La fonctionnalité du curseur peut être adaptée dans le cadre des restrictions actuelles sur les traductions.
EWIs connexes¶
SSC-EWI-0027 : L’instruction suivante utilise une variable/un littéral avec une requête non valide et ne sera pas exécutée.
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.
SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE consultez l’implémentation UDF.
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-PRF-0004: Cette instruction a des utilisations de curseur For Loop.
SSC-EWI-0030: L’instruction ci-dessous a des utilisations de Dynamic SQL
CONTINUE¶
Référence de traduction pour convertir l’instruction Oracle CONTINUE en instruction Snowflake Scripting
Description¶
L’instruction
CONTINUEquitte l’itération actuelle d’une boucle, conditionnellement ou inconditionnellement, et transfère le contrôle à l’itération suivante de la boucle actuelle ou d’une boucle étiquetée englobante.\ (Référence linguistique Oracle PL/SQL Instruction CONTINUE).
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Syntaxe CONTINUE Oracle¶
CONTINUE [ label ] [ WHEN boolean_expression ] ;
Syntaxe CONTINUE Snowflake Scripting¶
{ CONTINUE | ITERATE } [ <label> ] ;
Modèles d’échantillons de sources¶
1. Simple Continue¶
Le code ignore l’instruction INSERT en utilisant CONTINUE.
Remarque
Ce cas est équivalent sur le plan fonctionnel.
Oracle¶
CREATE TABLE continue_testing_table_1 (iterator VARCHAR2(5));
CREATE OR REPLACE PROCEDURE continue_procedure_1
IS
I NUMBER := 0;
J NUMBER := 20;
BEGIN
WHILE I <= J LOOP
I := I + 1;
CONTINUE;
INSERT INTO continue_testing_table_1
VALUES (TO_CHAR(I));
END LOOP;
END;
CALL continue_procedure_1();
SELECT * FROM continue_testing_table_1;
Résultat¶
ITERATOR |
|---|
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE continue_testing_table_1 (iterator VARCHAR(5))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE continue_procedure_1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 20;
BEGIN
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
I := :I + 1;
CONTINUE;
INSERT INTO continue_testing_table_1
VALUES (TO_CHAR(:I));
END LOOP;
END;
$$;
CALL continue_procedure_1();
SELECT * FROM
continue_testing_table_1;
Résultat¶
ITERATOR |
|---|
2. Continue with condition¶
Le code ignore l’insertion des nombres pairs en utilisant CONTINUE.
Note
Ce cas n’est pas équivalent sur le plan fonctionnel, mais vous pouvez transformer la condition en une instruction IF.
Oracle¶
CREATE TABLE continue_testing_table_2 (iterator VARCHAR2(5));
CREATE OR REPLACE PROCEDURE continue_procedure_2
IS
I NUMBER := 0;
J NUMBER := 20;
BEGIN
WHILE I <= J LOOP
I := I + 1;
CONTINUE WHEN MOD(I,2) = 0;
INSERT INTO continue_testing_table_2 VALUES(TO_CHAR(I));
END LOOP;
END;
CALL continue_procedure_2();
SELECT * FROM continue_testing_table_2;
Résultat¶
ITERATOR |
|---|
1 |
3 |
5 |
7 |
9 |
11 |
13 |
15 |
17 |
19 |
21 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE continue_testing_table_2 (iterator VARCHAR(5))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE continue_procedure_2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 20;
BEGIN
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
I := :I + 1;
IF (MOD(:I,2) = 0) THEN
CONTINUE;
END IF;
INSERT INTO continue_testing_table_2
VALUES(TO_CHAR(:I));
END LOOP;
END;
$$;
CALL continue_procedure_2();
SELECT * FROM
continue_testing_table_2;
Résultat¶
ITERATOR |
|---|
1 |
3 |
5 |
7 |
9 |
11 |
13 |
15 |
17 |
19 |
21 |
3. Continue with label and condition¶
Le code ignore la ligne 19 et la boucle intérieure n’est exécutée qu’une seule fois parce que CONTINUE passe toujours à la boucle extérieure à l’aide de l’étiquette.
Remarque
Ce cas est équivalent sur le plan fonctionnel à l’application du même processus que l’échantillon précédent.
Note
Notez que les étiquettes seront commentées.
Oracle¶
CREATE OR REPLACE PROCEDURE continue_procedure_3
IS
I NUMBER := 0;
J NUMBER := 10;
K NUMBER := 0;
BEGIN
<<out_loop>>
WHILE I <= J LOOP
I := I + 1;
INSERT INTO continue_testing_table_3 VALUES('I' || TO_CHAR(I));
<<in_loop>>
WHILE K <= J * 2 LOOP
K := K + 1;
CONTINUE out_loop WHEN K > J / 2;
INSERT INTO continue_testing_table_3 VALUES('K' || TO_CHAR(K));
END LOOP in_loop;
K := 0;
END LOOP out_loop;
END;
CALL continue_procedure_3();
SELECT * FROM continue_testing_table_3;
Résultat¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
I2 |
I3 |
I4 |
I5 |
I6 |
I7 |
I8 |
I9 |
I10 |
I11 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE continue_procedure_3 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 10;
K NUMBER(38, 18) := 0;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<out_loop>> ***/!!!
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
I := :I + 1;
INSERT INTO continue_testing_table_3
VALUES('I' || NVL(TO_CHAR(:I) :: STRING, ''));
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<in_loop>> ***/!!!
WHILE (:K <= :J * 2)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
K := :K + 1;
IF (:K > :J / 2) THEN
CONTINUE out_loop;
END IF;
INSERT INTO continue_testing_table_3
VALUES('K' || NVL(TO_CHAR(:K) :: STRING, ''));
END LOOP in_loop;
K := 0;
END LOOP out_loop;
END;
$$;
CALL continue_procedure_3();
SELECT * FROM
continue_testing_table_3;
Résultat¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
I2 |
I3 |
I4 |
I5 |
I6 |
I7 |
I8 |
I9 |
I10 |
I11 |
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
SSC-EWI-0094: La déclaration des étiquettes n’est pas prise en charge.
DECLARE¶
Référence de traduction pour convertir l’instruction Oracle DECLARE en instruction Snowflake Scripting
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
L’instruction Oracle DECLARE est une partie facultative de l’instruction de bloc PL/SQL. Elle permet la création de variables, de constantes, de déclarations et de définitions de procédures, de déclarations et de définitions de fonctions, d’exceptions, de curseurs, de types et de bien d’autres instructions. Pour plus d’informations sur Oracle DECLARE, cliquez ici.
Syntaxe DECLARE Oracle¶
declare_section body
declare_section::= { item_list_1 [ item_list_2 ] | item_list_2 }
item_list_1::=
{ type_definition
| cursor_declaration
| item_declaration
| function_declaration
| procedure_declaration
}
...
item_list_2::=
{ cursor_declaration
| cursor_definition
| function_declaration
| function_definition
| procedure_declaration
| procedure_definition
}
...
item_declaration::=
{ collection_variable_decl
| constant_declaration
| cursor_variable_declaration
| exception_declaration
| record_variable_declaration
| variable_declaration
}
body::= BEGIN statement ...
[ EXCEPTION exception_handler [ exception_handler ]... ] END [ name ] ;
Syntaxe DECLARE Snowflake Scripting¶
[ DECLARE
{ <variable_declaration> | <cursor_declaration> | <exception_declaration> | <resultset_declaration> }
[, { <variable_declaration> | <cursor_declaration> | <exception_declaration> | <resultset_declaration> } ... ]
]
BEGIN
<statement>;
[ <statement>; ... ]
[ EXCEPTION <exception_handler> ]
END [ <label> ] ;
Modèles d’échantillons de sources¶
Déclaration de variables¶
Syntaxe de déclaration des variables Oracle¶
variable_declaration::=
variable datatype [ [ NOT NULL] {:= | DEFAULT} expression ] ;
Syntaxe de déclaration des variables Snowflake Scripting¶
<variable_name> <type>;
<variable_name> DEFAULT <expression> ;
<variable_name> <type> DEFAULT <expression> ;
Oracle¶
CREATE OR REPLACE PROCEDURE var_decl_proc
IS
var1 NUMBER;
var2 NUMBER := 1;
var3 NUMBER NOT NULL := 1;
var4 NUMBER DEFAULT 1;
var5 NUMBER NOT NULL DEFAULT 1;
BEGIN
NULL;
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE var_decl_proc ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
var1 NUMBER(38, 18);
var2 NUMBER(38, 18) := 1;
var3 NUMBER(38, 18) := 1 /*** SSC-FDM-OR0025 - NOT NULL CONSTRAINT IS NOT SUPPORTED BY SNOWFLAKE ***/;
var4 NUMBER(38, 18) DEFAULT 1;
var5 NUMBER(38, 18) DEFAULT 1 /*** SSC-FDM-OR0025 - NOT NULL CONSTRAINT IS NOT SUPPORTED BY SNOWFLAKE ***/;
BEGIN
NULL;
END;
$$;
Déclaration de constantes¶
Avertissement
Les constantes ne sont pas prises en charge dans Snowflake Scripting, mais elles sont transformées en variables pour simuler le comportement.
Syntaxe de déclaration constante Oracle¶
constant_declaration::=
constant CONSTANT datatype [NOT NULL] { := | DEFAULT } expression ;
Syntaxe de déclaration des variables Snowflake Scripting¶
<variable_name> <type>;
<variable_name> DEFAULT <expression> ;
<variable_name> <type> DEFAULT <expression> ;
Oracle¶
CREATE OR REPLACE PROCEDURE const_decl_proc
IS
my_const1 CONSTANT NUMBER := 40;
my_const2 CONSTANT NUMBER NOT NULL := 40;
my_const2 CONSTANT NUMBER DEFAULT 40;
my_const2 CONSTANT NUMBER NOT NULL DEFAULT 40;
BEGIN
NULL;
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE const_decl_proc ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
my_const1 NUMBER(38, 18) := 40;
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
--** SSC-FDM-OR0025 - NOT NULL CONSTRAINT IS NOT SUPPORTED BY SNOWFLAKE **
my_const2 NUMBER(38, 18) := 40;
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
my_const2 NUMBER(38, 18) DEFAULT 40;
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
--** SSC-FDM-OR0025 - NOT NULL CONSTRAINT IS NOT SUPPORTED BY SNOWFLAKE **
my_const2 NUMBER(38, 18) DEFAULT 40;
BEGIN
NULL;
END;
$$;
Déclaration de curseurs¶
Syntaxe de déclaration de curseur Oracle¶
cursor_declaration::= CURSOR cursor
[( cursor_parameter_dec [, cursor_parameter_dec ]... )]
RETURN rowtype;
cursor_parameter_dec::= parameter [IN] datatype [ { := | DEFAULT } expression ]
rowtype::=
{ {db_table_or_view | cursor | cursor_variable}%ROWTYPE
| record%TYPE
| record_type
}
Syntaxe de déclaration de curseur dans Snowflake Scripting¶
<cursor_name> CURSOR [ ( <argument> [, <argument> ... ] ) ]
FOR <query> ;
Danger
La _ déclaration de curseur _ Oracle n’est pas une exigence et peut donc être commentée dans le code de sortie. La _ définition de curseur _ sera utilisée à la place de et elle sera convertie en _ déclaration de curseur _ de Snowflake Scripting. Veuillez consulter la section CURSOR pour obtenir plus d’informations sur la définition du curseur.
Déclaration d’exceptions¶
La déclaration d’exceptions peut parfois être suivie de l’initialisation de l’exception, la transformation actuelle prend les deux et les fusionne dans la déclaration d’exception de Snowflake Scripting. Le PRAGMA EXCEPTION_INIT d’origine sera commenté.
Syntaxe de déclaration des exceptions Oracle¶
exception_declaration::= exception EXCEPTION;
PRAGMA EXCEPTION_INIT ( exception, error_code ) ;
Syntaxe de déclaration des exceptions dans Snowflake Scripting¶
<exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
Oracle¶
CREATE OR REPLACE PROCEDURE procedure_exception
IS
my_exception EXCEPTION;
my_exception2 EXCEPTION;
PRAGMA EXCEPTION_INIT ( my_exception2, -20100 );
my_exception3 EXCEPTION;
PRAGMA EXCEPTION_INIT ( my_exception3, -19000 );
BEGIN
NULL;
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE procedure_exception ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
my_exception EXCEPTION;
my_exception2 EXCEPTION (-20100, '');
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0051 - PRAGMA EXCEPTION_INIT IS NOT SUPPORTED ***/!!!
PRAGMA EXCEPTION_INIT ( my_exception2, -20100 );
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0099 - EXCEPTION CODE NUMBER EXCEEDS SNOWFLAKE SCRIPTING LIMITS ***/!!!
my_exception3 EXCEPTION;
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0051 - PRAGMA EXCEPTION_INIT IS NOT SUPPORTED ***/!!!
PRAGMA EXCEPTION_INIT ( my_exception3, -19000 );
BEGIN
NULL;
END;
$$;
Cas non pris en charge¶
Les instructions de déclaration Oracle suivantes ne sont pas prises en charge par le bloc de déclaration Snowflake Scripting :
Déclaration des variables de curseur.
Déclaration des variables de collection.
Enregistrement de la déclaration des variables.
Définition du type (toutes ses variantes).
Déclaration et définition des fonctions.
Déclaration et définition des procédures.
Problèmes connus¶
1. The variable declarations with NOT NULL constraints are not supported by Snow Scripting.¶
La création de variables avec la contrainte NOT NULL provoque une erreur dans Snow Scripting.
2. The cursor declaration has no equivalent to Snowflake Scripting.¶
La déclaration de curseur Oracle est inutile et peut donc être commentée dans le code de sortie. La définition de curseur sera utilisée à la place et sera convertie en déclaration de curseur Snowflake Scripting.
3. The exception code exceeds Snowflake Scripting limits.¶
Le code d’exception Oracle est supprimé lorsqu’il dépasse les limites du code Snowflake Scripting. Le code d’exception doit être un entier compris entre -20000 et -20999.
3. The not supported cases.¶
Certaines instructions de déclaration Oracle ne sont pas prises en charge par le bloc de déclaration de Snowflake Scripting. Elles peuvent donc faire l’objet d’un commentaire et d’un avertissement.
connexesEWIS¶
SSC-EWI-OR0051: PRAGMA EXCEPTION_INIT n’est pas pris en charge.
SSC-EWI-OR0099: Le code d’exception dépasse la limite de Snowflake Scripting.
SSC-FDM-0016: Les constantes ne sont pas prises en charge par Snowflake Scripting. Elles sont transformées en variable.
SSC-FDM-OR0025: La contrainte non nulle n’est pas prise en charge dans les procédures Snowflake.
DEFAULT PARAMETERS¶
Cet article traite de la transformation actuelle des paramètres par défaut et de la manière dont leur fonctionnalité est émulée.
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
Un paramètre par défaut est un paramètre qui a une valeur si un argument n’est pas transmis dans la procédure ou l’appel de fonction. Comme Snowflake ne prend pas en charge les paramètres par défaut, SnowConvert AI insère la valeur par défaut dans la procédure ou l’appel de fonction.
Dans la déclaration, la clause DEFAULT VALUE du paramètre est supprimée. Les deux syntaxes, le symbole := et la clause DEFAULT, sont prises en charge.
Modèles d’échantillons de sources¶
Échantillon de code auxiliaire¶
Oracle¶
CREATE TABLE TABLE1(COL1 NUMBER, COL2 NUMBER);
CREATE TABLE TABLE2(COL1 NUMBER, COL2 NUMBER, COL2 NUMBER);0016
Snowflake¶
CREATE OR REPLACE TABLE TABLE1 (COL1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
COL2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE TABLE TABLE2 (COL1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
COL2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
COL2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Déclaration des paramètres par défaut¶
Oracle¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_PARAMS1 (
param1 NUMBER,
param2 NUMBER default TO_NUMBER(1)
)
AS
BEGIN
INSERT INTO TABLE1 (COL1, COL2)
VALUES(param1, param2);
END;
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_PARAMS2 (
param1 NUMBER default 1,
param2 NUMBER default 2
)
AS
BEGIN
INSERT INTO TABLE1 (COL1, COL2)
VALUES(param1, param2);
END;
CREATE OR REPLACE PROCEDURE PROCEDURE_WITH_DEAFAULT_PARAMS3 (
param1 NUMBER DEFAULT 100,
param2 NUMBER,
param3 NUMBER DEFAULT 1000
)
IS
BEGIN
INSERT INTO TABLE2(COL1, COL2, COL3)
VALUES (param1, param2, param3);
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_PARAMS1 (param1 NUMBER(38, 18),
param2 NUMBER(38, 18) DEFAULT TO_NUMBER(1)
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO TABLE1(COL1, COL2)
VALUES(:param1, :param2);
END;
$$;
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_PARAMS2 (
param1 NUMBER(38, 18) DEFAULT 1,
param2 NUMBER(38, 18) DEFAULT 2
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO TABLE1(COL1, COL2)
VALUES(:param1, :param2);
END;
$$;
CREATE OR REPLACE PROCEDURE PROCEDURE_WITH_DEAFAULT_PARAMS3 (
param1 NUMBER(38, 18) DEFAULT 100, param2 NUMBER(38, 18),
param3 NUMBER(38, 18) DEFAULT 1000
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO TABLE2(COL1, COL2, COL3)
VALUES (:param1, :param2, :param3);
END;
$$;
Appel de procédures avec des paramètres par défaut¶
Oracle¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_CALLS
AS
BEGIN
PROC_WITH_DEFAULT_PARAMS1(10, 15);
PROC_WITH_DEFAULT_PARAMS1(10);
PROC_WITH_DEFAULT_PARAMS2(10, 15);
PROC_WITH_DEFAULT_PARAMS2(10);
PROC_WITH_DEFAULT_PARAMS2();
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_CALLS ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CALL
PROC_WITH_DEFAULT_PARAMS1(10, 15);
CALL
PROC_WITH_DEFAULT_PARAMS1(10);
CALL
PROC_WITH_DEFAULT_PARAMS2(10, 15);
CALL
PROC_WITH_DEFAULT_PARAMS2(10);
CALL
PROC_WITH_DEFAULT_PARAMS2();
END;
$$;
Afin de vérifier que la fonctionnalité est correctement émulée, la requête suivante va exécuter la procédure et un SELECT à partir de la table mentionnée précédemment.
Oracle¶
CALL PROC_WITH_DEFAULT_CALLS();
SELECT * FROM TABLE1;
Résultat¶
COL1 |
COL2 |
|---|---|
10 |
15 |
10 |
1 |
10 |
15 |
10 |
2 |
1 |
2 |
Exécution de scripts Snowflake¶
CALL PROC_WITH_DEFAULT_CALLS();
SELECT * FROM TABLE1;
Résultat¶
COL1 |
COL2 |
|---|---|
10 |
15 |
10 |
1 |
10 |
15 |
10 |
2 |
1 |
2 |
Appel de procédures avec des arguments nommés et des paramètres par défaut¶
Oracle¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_CALLS2
AS
BEGIN
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 20, 30);
PROCEDURE_WITH_DEAFAULT_PARAMS3(param1 => 10, param2 => 20, param3 => 30);
PROCEDURE_WITH_DEAFAULT_PARAMS3(param3 => 10, param1 => 20, param2 => 30);
PROCEDURE_WITH_DEAFAULT_PARAMS3(param3 => 10, param2 => 30);
PROCEDURE_WITH_DEAFAULT_PARAMS3(param2 => 10, param3 => 30);
PROCEDURE_WITH_DEAFAULT_PARAMS3(param2 => 10);
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE PROC_WITH_DEFAULT_CALLS2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 20, 30);
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 20, 30);
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 20, 30);
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 30);
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10, 30);
CALL
PROCEDURE_WITH_DEAFAULT_PARAMS3(10);
END;
$$;
Afin de vérifier que la fonctionnalité est correctement émulée, la requête suivante va exécuter la procédure et un SELECT à partir de la table mentionnée précédemment.
Oracle¶
CALL PROC_WITH_DEFAULT_CALLS2();
SELECT * FROM TABLE2;
Résultat¶
COL1 |
COL2 |
COL3 |
|---|---|---|
10 |
20 |
30 |
10 |
20 |
30 |
20 |
30 |
10 |
100 |
30 |
10 |
100 |
10 |
30 |
100 |
10 |
1000 |
Exécution de scripts Snowflake¶
CALL PROC_WITH_DEFAULT_CALLS2();
SELECT * FROM TABLE2;
Résultat¶
COL1 |
COL2 |
COL3 |
|---|---|---|
10 |
20 |
30 |
10 |
20 |
30 |
20 |
30 |
10 |
100 |
30 |
10 |
100 |
10 |
30 |
100 |
10 |
1000 |
Problèmes connus¶
1. Aucun problème n’a été trouvé
EWIs connexes¶
Pas d’EWIs connexes.
EXECUTE IMMEDIATE¶
Référence de traduction pour convertir Oracle EXECUTE IMMEDIATE en instruction Snowflake Scripting
Description¶
L’instruction
EXECUTEIMMEDIATEconstruit et exécute une instruction dynamique SQL en une seule opération.La version dynamique native de SQL utilise l’instruction
EXECUTEIMMEDIATEpour traiter la plupart des instructions dynamiques SQL. (Référence linguistique Oracle PL/SQL Instruction EXECUTE IMMEDIATE)
Syntaxe EXECUTE IMMEDIATE Oracle¶
EXECUTE IMMEDIATE <dynamic statement> [<additional clause> , ...];
dynamic statement::= { '<string literal>' | <variable> }
additional clauses::=
{ <into clause> [<using clause>]
| <bulk collect into clause> [<using clause>]
| <using clause> [<dynamic return clause>]
| <dynamic return clasue> }
Snowflake Scripting prend en charge cette instruction, avec toutefois quelques différences fonctionnelles. Pour plus d’informations sur l’homologue de Snowflake, consultez la documentation sur Snowflake EXECUTE IMMEDIATE.
Syntaxe EXECUTE IMMEDIATE Snowflake Scripting¶
EXECUTE IMMEDIATE <dynamic statement> ;
dynamic statement::= {'<string literal>' | <variable> | $<session variable>}
Modèles d’échantillons de sources¶
Les échantillons suivants créent une table et tentent de la supprimer à l’aide de la fonction Execute Immediate.
Utilisation d’une chaîne codée en dur¶
Oracle¶
CREATE TABLE immediate_dropped_table(
col1 INTEGER
);
CREATE OR REPLACE PROCEDURE dropping_procedure
AS BEGIN
EXECUTE IMMEDIATE 'DROP TABLE immediate_dropped_table PURGE';
END;
CALL dropping_procedure();
SELECT * FROM immediate_dropped_table;
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE immediate_dropped_table (
col1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE dropping_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'DROP TABLE immediate_dropped_table';
END;
$$;
CALL dropping_procedure();
SELECT * FROM
immediate_dropped_table;
Stockage de la chaîne dans une variable¶
Oracle¶
CREATE TABLE immediate_dropped_table(
col1 INTEGER
);
CREATE OR REPLACE PROCEDURE dropping_procedure
AS
BEGIN
DECLARE
statement_variable VARCHAR2(500) := 'DROP TABLE immediate_dropped_table PURGE';
BEGIN
EXECUTE IMMEDIATE statement_variable;
END;
END;
CALL dropping_procedure();
SELECT * FROM immediate_dropped_table;
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE immediate_dropped_table (
col1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE dropping_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DECLARE
statement_variable VARCHAR(500) := 'DROP TABLE immediate_dropped_table';
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :statement_variable;
END;
END;
$$;
CALL dropping_procedure();
SELECT * FROM
immediate_dropped_table;
Concaténation des paramètres dans une instruction dynamique¶
Oracle¶
CREATE TABLE immediate_dropped_table(
col1 INTEGER
);
CREATE OR REPLACE PROCEDURE dropping_procedure(param1 VARCHAR2)
AS
BEGIN
DECLARE
statement_variable VARCHAR2(500) := 'DROP TABLE ' || param1 || ' PURGE';
BEGIN
EXECUTE IMMEDIATE statement_variable;
END;
END;
CALL dropping_procedure();
SELECT * FROM immediate_dropped_table;
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE immediate_dropped_table (
col1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE dropping_procedure (param1 VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DECLARE
statement_variable VARCHAR(500) := 'DROP TABLE ' || NVL(:param1 :: STRING, '');
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :statement_variable;
END;
END;
$$;
CALL dropping_procedure();
SELECT * FROM
immediate_dropped_table;
Transformation de clause USING¶
Oracle¶
CREATE TABLE immediate_inserted_table(COL1 INTEGER);
CREATE OR REPLACE PROCEDURE inserting_procedure_using(param1 INTEGER)
AS
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO immediate_inserted_table VALUES (:1)' USING param1;
END;
CALL inserting_procedure_using(1);
SELECT * FROM immediate_inserted_table;
Résultats¶
COL1 |
|---|
1 |
Exécution de scripts Snowflake¶
Note
Veuillez noter que les parenthèses sont exigées pour les paramètres de la clause USING dans Snowflake Scripting.
CREATE OR REPLACE TABLE immediate_inserted_table (COL1 INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE inserting_procedure_using (param1 INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO immediate_inserted_table
VALUES (?)' USING ( param1);
END;
$$;
CALL inserting_procedure_using(1);
SELECT * FROM
immediate_inserted_table;
Résultats¶
COL1 |
|---|
1 |
Problèmes connus¶
1. Immediate Execution results cannot be stored in variables.¶
SnowScripting ne prend pas en charge les clauses INTO et BULK COLLECT INTO. Pour cette raison, les résultats devront être transmis par d’autres moyens.
2. Numeric Placeholders¶
Les noms numériques des espaces réservés ne sont actuellement pas reconnus par SnowConvert AI, mais il existe un document de travail pour résoudre ce problème.
3. Argument Expressions are not supported by Snowflake Scripting¶
Dans Oracle, il est possible d’utiliser des expressions comme arguments pour la clause d’utilisation ; cependant, ce cas n’est pas pris en charge par Snowflake Scripting, et elles sont commentées.
4. Dynamic SQL Execution queries may be marked incorrectly as non-runnable.¶
Dans certains cas, une instruction d’exécution peut faire l’objet d’un commentaire, que son exécution soit sûre ou non, veuillez en tenir compte :
Oracle¶
CREATE OR REPLACE PROCEDURE inserting_procedure_variable_execute_concatenation_parameter(param1 INTEGER)
IS
query VARCHAR2(500) := 'INSERT INTO immediate_inserted_table VALUES (';
BEGIN
EXECUTE IMMEDIATE query || param1 || ')';
END;
Exécution de scripts Snowflake¶
Note
Veuillez noter que les parenthèses sont exigées pour les paramètres de la clause USING dans Snowflake Scripting.
CREATE OR REPLACE PROCEDURE inserting_procedure_variable_execute_concatenation_parameter (param1 INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
query VARCHAR(500) := 'INSERT INTO immediate_inserted_table VALUES (';
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
!!!RESOLVE EWI!!! /*** SSC-EWI-0027 - THE FOLLOWING STATEMENT USES A VARIABLE/LITERAL WITH AN INVALID QUERY AND IT WILL NOT BE EXECUTED ***/!!!
EXECUTE IMMEDIATE NVL(:query :: STRING, '') || NVL(:param1 :: STRING, '') || ')';
END;
$$;
EWIs connexes¶
SSC-EWI-0027: Variable avec requête non valide.
SSC-EWI-0030: L’instruction ci-dessous a des utilisations de Dynamic SQL.
EXIT¶
Référence de traduction pour convertir l’instruction Oracle EXIT en instruction Snowflake Scripting
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
L’instruction
EXITquitte l’itération actuelle d’une boucle, conditionnellement ou inconditionnellement, et transfère le contrôle à la fin de la boucle actuelle ou à une boucle étiquetée englobante.\ (Référence linguistique Oracle PL/SQL Instruction EXIT).
Syntaxe EXIT Oracle¶
EXIT [ label ] [ WHEN boolean_expression ] ;
Syntaxe EXIT Snowflake Scripting¶
{ BREAK | EXIT } [ <label> ] ;
Modèles d’échantillons de sources¶
Note
Notez que vous pouvez remplacer EXITpar BREAKet que tout fonctionnera de la même manière.
1. Simple Exit¶
Le code ignore l’instruction INSERT en utilisant EXIT.
Remarque
Ce cas est équivalent sur le plan fonctionnel.
Oracle¶
CREATE TABLE exit_testing_table_1 (
iterator VARCHAR2(5)
);
CREATE OR REPLACE PROCEDURE exit_procedure_1
IS
I NUMBER := 0;
J NUMBER := 20;
BEGIN
WHILE I <= J LOOP
I := I + 1;
EXIT;
INSERT INTO exit_testing_table_1 VALUES(TO_CHAR(I));
END LOOP;
END;
CALL exit_procedure_1();
SELECT * FROM exit_testing_table_1;
Résultat¶
ITERATOR |
|---|
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE exit_testing_table_1 (
iterator VARCHAR(5)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
;
CREATE OR REPLACE PROCEDURE exit_procedure_1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 20;
BEGIN
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
I := :I + 1;
EXIT;
INSERT INTO exit_testing_table_1
VALUES(TO_CHAR(:I));
END LOOP;
END;
$$;
CALL exit_procedure_1();
SELECT * FROM
exit_testing_table_1;
Résultat¶
ITERATOR |
|---|
2. Exit with condition¶
Le code quitte la boucle lorsque l’itérateur est supérieur à 5.
Remarque
Ce cas est fonctionnellement équivalent en transformant la condition en une instruction IF.
Oracle¶
CREATE TABLE exit_testing_table_2 (
iterator VARCHAR2(5)
);
CREATE OR REPLACE PROCEDURE exit_procedure_2
IS
I NUMBER := 0;
J NUMBER := 20;
BEGIN
WHILE I <= J LOOP
EXIT WHEN I > 5;
I := I + 1;
INSERT INTO exit_testing_table_2 VALUES(TO_CHAR(I));
END LOOP;
END;
CALL exit_procedure_2();
SELECT * FROM exit_testing_table_2;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE exit_testing_table_2 (
iterator VARCHAR(5)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
;
CREATE OR REPLACE PROCEDURE exit_procedure_2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 20;
BEGIN
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
IF (:I > 5) THEN
EXIT;
END IF;
I := :I + 1;
INSERT INTO exit_testing_table_2
VALUES(TO_CHAR(:I));
END LOOP;
END;
$$;
CALL exit_procedure_2();
SELECT * FROM
exit_testing_table_2;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
3. Exit with label and condition¶
Le code casse les deux boucles en utilisant l’instruction EXIT qui pointe vers la boucle extérieure.
Remarque
Ce cas est équivalent sur le plan fonctionnel à l’application du même processus que l’échantillon précédent.
Note
Notez que les étiquettes seront commentées.
Oracle¶
CREATE TABLE exit_testing_table_3 (
iterator VARCHAR2(5)
);
CREATE OR REPLACE PROCEDURE exit_procedure_3
IS
I NUMBER := 0;
J NUMBER := 10;
K NUMBER := 0;
BEGIN
<<out_loop>>
WHILE I <= J LOOP
I := I + 1;
INSERT INTO exit_testing_table_3 VALUES('I' || TO_CHAR(I));
<<in_loop>>
WHILE K <= J * 2 LOOP
K := K + 1;
EXIT out_loop WHEN K > J / 2;
INSERT INTO exit_testing_table_3 VALUES('K' || TO_CHAR(K));
END LOOP in_loop;
K := 0;
END LOOP out_loop;
END;
CALL exit_procedure_3();
SELECT * FROM exit_testing_table_3;
Résultat¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE exit_testing_table_3 (
iterator VARCHAR(5)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
;
CREATE OR REPLACE PROCEDURE exit_procedure_3 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 0;
J NUMBER(38, 18) := 10;
K NUMBER(38, 18) := 0;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<out_loop>> ***/!!!
WHILE (:I <= :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
I := :I + 1;
INSERT INTO exit_testing_table_3
VALUES('I' || NVL(TO_CHAR(:I) :: STRING, ''));
!!!RESOLVE EWI!!! /*** SSC-EWI-0094 - LABEL DECLARATION FOR A STATEMENT IS NOT SUPPORTED BY SNOWFLAKE SCRIPTING <<in_loop>> ***/!!!
WHILE (:K <= :J * 2)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
K := :K + 1;
IF (:K > :J / 2) THEN
EXIT out_loop;
END IF;
INSERT INTO exit_testing_table_3
VALUES('K' || NVL(TO_CHAR(:K) :: STRING, ''));
END LOOP in_loop;
K := 0;
END LOOP out_loop;
END;
$$;
CALL exit_procedure_3();
SELECT * FROM
exit_testing_table_3;
Résultat¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
SSC-EWI-0094: La déclaration des étiquettes n’est pas prise en charge.
EXPRESSIONS¶
Référence de traduction des expressions Oracle à Snow Scripting
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
La table suivante résume la manière de transformer les différents types d’expression Oracle en Snowflake Scripting.
Syntaxe |
Statut de conversion |
Remarques |
|---|---|---|
Partiel |
||
Partiel |
||
Partiel |
||
Partiel |
||
Complet |
N/A |
|
Complet |
N/A |
|
Non traduit |
Snowflake n’a pas d’équivalent natif pour les collections Oracle. Voir Collections et enregistrements. |
|
Non traduit |
Snowflake n’a pas d’équivalent natif pour les types d’enregistrement Oracle. Voir Collections et enregistrements. |
Scénarios communs partiellement pris en charge¶
Constantes Oracle¶
Oracle¶
CREATE TABLE EXPRESSIONS_TABLE(col VARCHAR(30));
CREATE OR REPLACE PROCEDURE EXPRESSIONS_SAMPLE
IS
RESULT VARCHAR(50);
CONST CONSTANT VARCHAR(20) := 'CONSTANT TEXT';
BEGIN
-- CONSTANT EXPRESSIONS
RESULT := CONST;
INSERT INTO EXPRESSIONS_TABLE(COL) VALUES (RESULT);
END;
CALL EXPRESSIONS_SAMPLE();
SELECT * FROM EXPRESSIONS_TABLE;
Résultat¶
COL |
|---|
CONSTANT TEXT |
Snowflake¶
CREATE OR REPLACE TABLE EXPRESSIONS_TABLE (col VARCHAR(30))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE EXPRESSIONS_SAMPLE ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
RESULT VARCHAR(50);
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
CONST VARCHAR(20) := 'CONSTANT TEXT';
BEGIN
-- CONSTANT EXPRESSIONS
RESULT := :CONST;
INSERT INTO EXPRESSIONS_TABLE(COL) VALUES (:RESULT);
END;
$$;
CALL EXPRESSIONS_SAMPLE();
SELECT * FROM
EXPRESSIONS_TABLE;
Résultat¶
COL |
|---|
CONSTANT TEXT |
Expressions numériques non prises en charge¶
Oracle¶
CREATE TABLE NUMERIC_EXPRESSIONS_TABLE(col number);
CREATE OR REPLACE PROCEDURE NUMERIC_EXPRESSIONS
IS
RESULT NUMBER;
CURSOR C1 IS SELECT * FROM NUMERIC_EXPRESSIONS_TABLE;
TYPE NUMERIC_TABLE IS TABLE OF NUMBER(10);
COLLECTION NUMERIC_TABLE;
BEGIN
-- CURSOR EXPRESSIONS
OPEN C1;
RESULT := C1%ROWCOUNT;
CLOSE C1;
INSERT INTO NUMERIC_EXPRESSIONS_TABLE(COL) VALUES (RESULT);
-- ** OPERATOR
RESULT := 10 ** 2;
INSERT INTO NUMERIC_EXPRESSIONS_TABLE(COL) VALUES (RESULT);
-- COLLECTION EXPRESSIONS
COLLECTION := NUMERIC_TABLE(1, 2, 3, 4, 5, 6);
RESULT := COLLECTION.COUNT + COLLECTION.FIRST;
INSERT INTO NUMERIC_EXPRESSIONS_TABLE(COL) VALUES (RESULT);
-- IMPLICIT CURSOR EXPRESSIONS
UPDATE NUMERIC_EXPRESSIONS_TABLE SET COL = COL + 4;
RESULT := SQL%ROWCOUNT;
INSERT INTO NUMERIC_EXPRESSIONS_TABLE(COL) VALUES (RESULT);
END;
CALL NUMERIC_EXPRESSIONS();
SELECT * FROM NUMERIC_EXPRESSIONS_TABLE;
Résultat¶
COL |
|---|
4 |
104 |
11 |
3 |
Expressions booléennes non prises en charge¶
Oracle¶
--Aux function to convert BOOLEAN to VARCHAR
CREATE OR REPLACE FUNCTION convert_bool(p1 in BOOLEAN)
RETURN VARCHAR
AS
var1 VARCHAR(20) := 'FALSE';
BEGIN
IF p1 THEN
var1 := 'TRUE';
END IF;
RETURN var1;
END;
--Table
CREATE TABLE t_boolean_table
(
conditional_predicate VARCHAR(20),
collection_variable VARCHAR(20),
sql_variable VARCHAR(20)
)
--Main Procedure
CREATE OR REPLACE PROCEDURE p_boolean_limitations
AS
TYPE varray_example IS VARRAY(4) OF VARCHAR(15);
colection_example varray_example := varray_example('John', 'Mary', 'Alberto', 'Juanita');
collection_variable BOOLEAN;
conditional_predicate BOOLEAN;
sql_variable BOOLEAN;
--Result variables
col1 VARCHAR(20);
col2 VARCHAR(20);
col3 VARCHAR(20);
BEGIN
--Conditional predicate
conditional_predicate := INSERTING;
--Collection.EXISTS(index)
collection_variable := colection_example.EXISTS(2);
--Cursor FOUND / NOTFOUND / ISOPEN
sql_variable:= SQL%FOUND OR SQL%NOTFOUND OR SQL%ISOPEN;
--Convert BOOLEAN to VARCHAR to insert
col1 := convert_bool(conditional_predicate);
col2 := convert_bool(collection_variable);
col3 := convert_bool(sql_variable);
INSERT INTO t_boolean_table VALUES (col1, col2, col3);
END;
CALL p_boolean_limitations();
SELECT * FROM t_boolean_table;
EWIs connexes.¶
SSC-FDM-0016: Les constantes ne sont pas prises en charge par Snowflake Scripting. Elles ont été transformées en variables.
FOR LOOP¶
Description¶
À chaque itération de l’instruction
FORLOOP, ses instructions sont exécutées, son index est incrémenté ou décrémenté et le contrôle revient au début de la boucle. (Référence linguistique PL/SQL Instructions FOR LOOP)
Syntaxe Oracle¶
FOR
pls_identifier [ MUTABLE | IMMUTABLE ] [ constrained_type ]
[ , iterand_decl ]
IN
[ REVERSE ] iteration_control pred_clause_seq
[, qual_iteration_ctl]...
LOOP
statement...
END LOOP [ label ] ;
Syntaxe Snowflake Scripting¶
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP }
statement;
[ statement; ... ]
END { FOR | LOOP } [ <label> ] ;
Snowflake Scripting prend en charge FOR LOOP qui boucle un nombre de fois spécifié. Les limites supérieure et inférieure doivent être INTEGER. Pour plus d’informations, consultez la documentation Snowflake Scripting.
Le comportement d’Oracle FOR LOOP peut également être modifié à l’aide des instructions :
Modèles d’échantillons de sources¶
1. FOR LOOP¶
Remarque
Ce cas est équivalent sur le plan fonctionnel.
Exemple FOR LOOP Oracle¶
CREATE OR REPLACE PROCEDURE P1
AS
BEGIN
FOR i IN 1..10
LOOP
NULL;
END LOOP;
FOR i IN VAR1..VAR2
LOOP
NULL;
END LOOP;
FOR i IN REVERSE 1+2..10+5
LOOP
NULL;
END LOOP;
END;
Exemple FOR LOOP Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE P1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN 1 TO 10
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN VAR1 TO VAR2
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN REVERSE 1+2 TO 10+5
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
END;
$$;
2. FOR LOOP with additional clauses¶
Exemple FOR LOOP Oracle¶
CREATE OR REPLACE PROCEDURE P2
AS
BEGIN
FOR i IN 1..10 WHILE i <= 5 LOOP
NULL;
END LOOP;
FOR i IN 5..15 BY 5 LOOP
NULL;
END LOOP;
END;
Exemple FOR LOOP Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE P2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0101 - FOR LOOP WITH "WHILE" CLAUSE IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
FOR i IN 1 TO 10
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0101 - FOR LOOP WITH "BY" CLAUSE IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN 5 TO 15
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
END;
$$;
3. FOR LOOP with multiple conditions¶
Exemple FOR LOOP Oracle¶
CREATE OR REPLACE PROCEDURE P3
AS
BEGIN
FOR i IN REVERSE 1..3,
REVERSE i+5..i+7
LOOP
NULL;
END LOOP;
END;
Exemple FOR LOOP Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE P3 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0100 - FOR LOOP WITH MULTIPLE CONDITIONS IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
FOR i IN REVERSE 1 TO 3
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
END;
$$;
4. FOR LOOP with unsupported format¶
Exemple FOR LOOP Oracle¶
CREATE OR REPLACE PROCEDURE P3
AS
TYPE values_aat IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
l_employee_values values_aat;
BEGIN
FOR power IN REPEAT power*2 WHILE power <= 64 LOOP
NULL;
END LOOP;
FOR i IN VALUES OF l_employee_values LOOP
NULL;
END LOOP;
END;
Exemple FOR LOOP Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE P3 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- TYPE values_aat IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
l_employee_values VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'values_aat' USAGE CHANGED TO VARIANT ***/!!!;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0103 - FOR LOOP FORMAT IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0101 - FOR LOOP WITH "WHILE" CLAUSE IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
FOR power IN REPEAT power*2 WHILE power <= 64
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0103 - FOR LOOP FORMAT IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
FOR i IN VALUES OF :l_employee_values
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
NULL;
END LOOP;
END;
$$;
Avertissement
La transformation des types personnalisés n’est actuellement pas prise en charge par Snowflake Scripting.
Problèmes connus¶
1. For With Multiple Conditions¶
Oracle autorise plusieurs conditions sur un même FOR LOOP, mais Snowflake Scripting n’autorise qu’une seule condition par FOR LOOP. Seule la première condition est migrée et les autres sont ignorées lors de la transformation. Voir SSC-FDM-OR0022.
Oracle¶
FOR i IN REVERSE 1..3,
REVERSE i+5..i+7
LOOP
NULL;
END LOOP;
Exemple FOR LOOP Snowflake Scripting¶
--** SSC-FDM-OR0022 - FOR LOOP WITH MULTIPLE CONDITIONS IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING **
FOR i IN REVERSE 1 TO 3 LOOP
NULL;
END LOOP;
2. Variable de compteur mutable ou non mutable
Oracle permet de modifier la valeur de la variable FOR LOOP à l’intérieur de la boucle. La documentation actuelle inclut cette fonctionnalité, mais Snowflake recommande de l’éviter. La modification de la valeur de cette variable peut ne pas se dérouler correctement dans Snowflake Scripting.
3. Nombre entier ou nombre flottant pour la limite supérieure ou inférieure
Snowflake Scripting autorise uniquement un INTEGER ou une expression qui correspond à un INTEGER en tant que limite pour la condition FOR LOOP. Les nombres flottants seront arrondis à la valeur supérieure ou inférieure et modifieront la limite d’origine.
4. Clauses non prises en charge par Oracle
Oracle autorise les clauses supplémentaires dans la condition FOR LOOP. Comme la clause BY pour un incrément graduel dans la condition. Et les clauses WHILE et WHEN pour les expressions booléennes. Ces clauses supplémentaires ne sont pas prises en charge dans Snowflake Scripting et sont ignorées lors de la transformation. Voir SSC-EWI-OR0101.
Oracle¶
FOR i IN 5..15 BY 5 LOOP
NULL;
END LOOP;
Exécution de scripts Snowflake¶
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0101 - FOR LOOP WITH "BY" CLAUSE IS CURRENTLY NOT SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
FOR i IN 5 TO 15 LOOP
NULL;
END LOOP;
5. Formats non pris en charge
Oracle autorise différents types de conditions pour une clause FOR LOOP. Il prend en charge les expressions booléennes, les collections, les enregistrements… Cependant, Snowflake Scripting ne prend en charge que FOR LOOP avec des entiers définis comme limites. Tous les autres formats sont marqués comme non pris en charge et nécessitent des opérations manuelles supplémentaires pour être transformés. Voir SSC-EWI-OR0103.
EWIs connexes¶
SSC-EWI-0058: La fonctionnalité n’est pas prise en charge actuellement par Snowflake Scripting.
SSC-EWI-0062: L’utilisation du type personnalisé a changé en variante.
SSC-EWI-OR0100: La clause For Loop avec plusieurs conditions n’est actuellement pas prise en charge par Snowflake Scripting. Seule la première condition est utilisée.
SSC-EWI-OR0101: La clause For Loop spécifique n’est actuellement pas prise en charge par Snowflake Scripting.
SSC-EWI-OR0103: Le format For Loop n’est actuellement pas pris en charge par Snowflake Scripting.
FORALL¶
Description¶
L’instruction
FORALLexécute une instruction DML plusieurs fois, avec des valeurs différentes dans les clausesVALUESetWHERE. (Référence linguistique Oracle PL/SQL Instruction FORALL).
Syntaxe Oracle¶
FORALL index IN bounds_clause [ SAVE ] [ EXCEPTIONS ] dml_statement ;
Avertissement
Snowflake Scripting n’a pas d’équivalence directe avec l’instruction FORALL, mais peut être émulé avec différentes solutions de contournement pour obtenir une équivalence fonctionnelle.
Modèles d’échantillons de sources¶
Données de configuration¶
Oracle¶
Tables 1¶
CREATE TABLE table1 (
column1 NUMBER,
column2 NUMBER
);
INSERT INTO table1 (column1, column2) VALUES (1, 2);
INSERT INTO table1 (column1, column2) VALUES (2, 3);
INSERT INTO table1 (column1, column2) VALUES (3, 4);
INSERT INTO table1 (column1, column2) VALUES (4, 5);
INSERT INTO table1 (column1, column2) VALUES (5, 6);
CREATE TABLE table2 (
column1 NUMBER,
column2 NUMBER
);
INSERT INTO table2 (column1, column2) VALUES (1, 2);
Tables 2¶
CREATE TABLE error_table (
ORA_ERR_NUMBER$ NUMBER,
ORA_ERR_MESG$ VARCHAR2(2000),
ORA_ERR_ROWID$ ROWID,
ORA_ERR_OPTYP$ VARCHAR2(2),
ORA_ERR_TAG$ VARCHAR2(2000)
);
--departments
CREATE TABLE parent_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10)
);
INSERT INTO parent_table VALUES (10, 'IT');
INSERT INTO parent_table VALUES (20, 'HR');
INSERT INTO parent_table VALUES (30, 'INFRA');
--employees
CREATE TABLE source_table(
Id INT PRIMARY KEY,
Name VARCHAR2(20) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
);
INSERT INTO source_table VALUES (101, 'Anurag111111111', 10);
INSERT INTO source_table VALUES (102, 'Pranaya11111111', 20);
INSERT INTO source_table VALUES (103, 'Hina11111111111', 30);
--a copy of source
CREATE TABLE target_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
);
INSERT INTO target_table VALUES (101, 'Anurag', 10);
Snowflake¶
Tables 1¶
CREATE OR REPLACE TABLE table1 (
column1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
column2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO table1(column1, column2) VALUES (1, 2);
INSERT INTO table1(column1, column2) VALUES (2, 3);
INSERT INTO table1(column1, column2) VALUES (3, 4);
INSERT INTO table1(column1, column2) VALUES (4, 5);
INSERT INTO table1(column1, column2) VALUES (5, 6);
CREATE OR REPLACE TABLE table2 (
column1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
column2 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO table2(column1, column2) VALUES (1, 2);
Tables 2¶
CREATE OR REPLACE TABLE error_table (
"ORA_ERR_NUMBER$" NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
"ORA_ERR_MESG$" VARCHAR(2000),
"ORA_ERR_ROWID$" VARCHAR(18) !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWID DATA TYPE CONVERTED TO VARCHAR ***/!!!,
"ORA_ERR_OPTYP$" VARCHAR(2),
"ORA_ERR_TAG$" VARCHAR(2000)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
--departments
CREATE OR REPLACE TABLE parent_table (
Id INT PRIMARY KEY,
Name VARCHAR(10)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO parent_table
VALUES (10, 'IT');
INSERT INTO parent_table
VALUES (20, 'HR');
INSERT INTO parent_table
VALUES (30, 'INFRA');
--employees
CREATE OR REPLACE TABLE source_table (
Id INT PRIMARY KEY,
Name VARCHAR(20) NOT NULL,
DepartmentID INT REFERENCES parent_table (Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO source_table
VALUES (101, 'Anurag111111111', 10);
INSERT INTO source_table
VALUES (102, 'Pranaya11111111', 20);
INSERT INTO source_table
VALUES (103, 'Hina11111111111', 30);
--a copy of source
CREATE OR REPLACE TABLE target_table (
Id INT PRIMARY KEY,
Name VARCHAR(10) NOT NULL,
DepartmentID INT REFERENCES parent_table (Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO target_table
VALUES (101, 'Anurag', 10);
1. FORALL With Collection of Records¶
Oracle¶
Remarque
Les trois cas ci-dessous ont la même transformation en Snowflake Scripting et sont fonctionnellement équivalents.
Source¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS SELECT * FROM table1;
TYPE tableType IS TABLE OF cursorVariable%ROWTYPE;
tableVariable tableType;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO tableVariable LIMIT 100;
EXIT WHEN tableVariable.COUNT = 0;
FORALL forIndex IN 1..tableVariable.COUNT
INSERT INTO table2 (column1, column2)
VALUES (tableVariable(forIndex).column1, tableVariable(forIndex).column2);
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|
1| 2|
1| 2|
2| 3|
3| 4|
4| 5|
5| 6|
Snowflake¶
FORALL avec collection d’enregistrements¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2(column1, column2)
(
SELECT
column1,
column2
FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
Note
Les EWIs SSC-PRF-0001 et SSC-PRF-0003 sont ajoutées à chaque occurrence de FETCH BULK COLLECT dans l’instruction FORALL.
2. FORALL With INSERT INTO¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
* FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
3. FORALL With Multiple Fetched Collections¶
Oracle¶
Avec INSERT INTO¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
column1Collection dbms_sql.NUMBER_table;
column2Collection dbms_sql.NUMBER_table;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO column1Collection, column2Collection limit 20;
EXIT WHEN column1Collection.COUNT = 0;
FORALL forIndex IN 1..column1Collection.COUNT
INSERT INTO table2 VALUES (
column1Collection(forIndex),
column2Collection(forIndex)
);
END LOOP;
CLOSE cursorVariable;
END;
Avec UPDATE¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
column1Collection dbms_sql.NUMBER_table;
column2Collection dbms_sql.NUMBER_table;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO column1Collection, column2Collection limit 2;
EXIT WHEN column1Collection.COUNT = 0;
FORALL forIndex IN 1..column1Collection.COUNT
UPDATE table2 SET column2 = column2Collection(forIndex)
WHERE column1 = column1Collection(forIndex);
END LOOP;
CLOSE cursorVariable;
END;
Résultats INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
1 |
2 |
Résultats UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2. |
Snowflake¶
Avec INSERT INTO¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
$1,
$2
FROM
table1
);
END;
$$;
Avec UPDATE¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column2 = column1Collection.$2
FROM
(
SELECT
* FROM
table1) AS column1Collection
WHERE
column1 = column1Collection.$1;
END;
$$;
Résultats INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
Résultats UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
4. FORALL With Record of Collections¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE recordType IS RECORD(
column1Collection dbms_sql.NUMBER_table,
column2Collection dbms_sql.NUMBER_table
);
columnRecord recordType;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO columnRecord.column1Collection, columnRecord.column2Collection limit 20;
FORALL forIndex IN 1..columnRecord.column1Collection.COUNT
INSERT INTO table2 VALUES (
columnRecord.column1Collection(forIndex),
columnRecord.column2Collection(forIndex)
);
EXIT WHEN cursorVariable%NOTFOUND;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL Scripting¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
$1,
$2
FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
5. FORALL With Dynamic SQL¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
cursorVariable SYS_REFCURSOR;
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
query VARCHAR(200) := 'SELECT * FROM table1';
BEGIN
OPEN cursorVariable FOR query;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
query VARCHAR(200) := 'SELECT * FROM
table1';
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'CREATE OR REPLACE TEMPORARY TABLE query AS ' || :query;
INSERT INTO table2
(
SELECT
*
FROM
query
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
6. FORALL With Literal SQL¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE SampleProcedure
IS
TYPE TabRecType IS RECORD (
column1 NUMBER,
column2 NUMBER
);
TYPE tabType IS TABLE OF TabRecType;
cursorRef SYS_REFCURSOR;
tab tabType;
BEGIN
OPEN cursorRef FOR 'SELECT src.column1, src.column2 FROM ' || 'table1' || ' src';
LOOP
BEGIN
FETCH cursorRef BULK COLLECT INTO tab LIMIT 1000;
FORALL i IN 1..tab.COUNT
INSERT INTO table2 (column1, column2)
VALUES (tab(i).column1, tab(i).column2);
EXIT WHEN cursorRef%NOTFOUND;
END;
END LOOP;
CLOSE cursorRef;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE SampleProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE TEMPORARY TABLE cursorRef_TEMP_TABLE AS ' || 'SELECT src.column1, src.column2 FROM ' || 'table1' || ' src';
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2(column1, column2)
(
SELECT
*
FROM
cursorRef_TEMP_TABLE
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
7. FORALL With Parametrized Cursors¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
intVariable INTEGER := 7;
CURSOR cursorVariable(param1 INTEGER, param2 INTEGER default 5) IS
SELECT * FROM table1
WHERE
column2 = intVariable OR
column1 BETWEEN param1 AND param2;
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable(1);
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 20;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
intVariable INTEGER := 7;
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
* FROM
table1
WHERE
column2 = :intVariable
OR
column1 BETWEEN 1 AND 5
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
8. FORALL Without LOOPS¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
SELECT * BULK COLLECT INTO collectionVariable FROM table1;
FORALL forIndex IN 1..collectionVariable.COUNT
INSERT INTO table2 VALUES (
collectionVariable (forIndex).column1,
collectionVariable (forIndex).column2
);
collectionVariable.DELETE;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
column1,
column2
FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
9. FORALL With UPDATE Statements¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
UPDATE table2 SET column1 = '54321' WHERE column2 = collectionVariable(forIndex).column2;
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column1 = '54321'
FROM
(
SELECT
* FROM
table1) AS collectionVariable
WHERE
column2 = collectionVariable.column2;
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
10. FORALL With DELETE Statements¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
DELETE FROM table2 WHERE column2 = collectionVariable(forIndex).column2;
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
no data found
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
DELETE FROM
table2
USING (
SELECT
* FROM
table1) collectionVariable
WHERE
table2.column2 = collectionVariable.column2;
END;
$$;
Résultats¶
Query produced no results
11. FORALL With PACKAGE References¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PACKAGE MyPackage AS
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
END;
/
CREATE OR REPLACE PROCEDURE InsertIntoPackage(param integer) IS
BEGIN
SELECT
param,
param BULK COLLECT INTO MyPackage.collectionVariable
FROM
DUAL;
END;
/
CREATE OR REPLACE PROCEDURE InsertUsingPackage IS
BEGIN
FORALL forIndex IN MyPackage.collectionVariable.FIRST..MyPackage.collectionVariable.LAST
INSERT INTO table2 VALUES MyPackage.collectionVariable(forIndex);
MyPackage.collectionVariable.DELETE;
END;
/
DECLARE
param_value INTEGER := 10;
BEGIN
InsertIntoPackage(param_value);
InsertUsingPackage;
END;
select * from table2;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
10 |
10 |
Snowflake¶
Équivalent FORALL¶
CREATE SCHEMA IF NOT EXISTS MyPackage
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0049 - PACKAGE TYPE DEFINITIONS in stateful package MyPackage are not supported yet ***/!!!
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
CREATE OR REPLACE TEMPORARY TABLE MYPACKAGE_COLLECTIONVARIABLE (
);
CREATE OR REPLACE PROCEDURE InsertIntoPackage (param integer)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DELETE FROM
MYPACKAGE_COLLECTIONVARIABLE;
INSERT INTO MYPACKAGE_COLLECTIONVARIABLE
(
SELECT
:param,
:param
FROM
DUAL
);
END;
$$;
CREATE OR REPLACE PROCEDURE InsertUsingPackage ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
*
FROM
MYPACKAGE_COLLECTIONVARIABLE
);
END;
$$;
DECLARE
param_value INTEGER := 10;
call_results VARIANT;
BEGIN
CALL
InsertIntoPackage(:param_value);
CALL
InsertUsingPackage();
RETURN call_results;
END;
select * from
table2;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
10.000000000000000000 |
10.000000000000000000 |
Avertissement
La transformation ci-dessus ne fonctionne que si la variable définie dans le paquet est un enregistrement de collections.
12. FORALL With MERGE Statements¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
MERGE INTO table2 tgt
USING (
SELECT
collectionVariable(forIndex).column1 column1,
collectionVariable(forIndex).column2 column2
FROM DUAL
) src
ON (tgt.column1 = src.column1)
WHEN MATCHED THEN
UPDATE SET
tgt.column2 = src.column2 * 2
WHEN NOT MATCHED THEN
INSERT (column1, column2)
VALUES (src.column1, src.column2);
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
4 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
MERGE INTO table2 tgt
USING (
SELECT
collectionVariable.column1 column1,
collectionVariable.column2 column2
FROM
(
SELECT
* FROM
table1
) collectionVariable
) src
ON (tgt.column1 = src.column1)
WHEN MATCHED THEN
UPDATE SET
tgt.column2 = src.column2 * 2
WHEN NOT MATCHED THEN
INSERT (column1, column2)
VALUES (src.column1, src.column2);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
1.000000000000000000 |
4.000000000000000000 |
Avertissement
La transformation ci-dessus ne fonctionne que si l’instruction SELECT à l’intérieur de MERGE sélectionne la table DUAL.
13. Default FORALL transformation¶
Note
Vous pouvez également être intéressé par aides de curseurs en masse.
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS SELECT * FROM table1;
TYPE columnsRecordType IS RECORD (column1 dbms_sql.NUMBER_table, column2 dbms_sql.NUMBER_table);
recordVariable columnsRecordType;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
col1 dbms_sql.NUMBER_table;
col2 dbms_sql.NUMBER_table;
BEGIN
OPEN cursorVariable;
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 (column1, column2)
VALUES (collectionVariable(forIndex).column1, collectionVariable(forIndex).column2);
FETCH cursorVariable BULK COLLECT INTO col1, col2 limit 2;
FORALL forIndex IN col1.FIRST..col1.LAST
INSERT INTO table2 (column1, column2)
VALUES (col1(forIndex), col2(forIndex));
LOOP
FETCH cursorVariable BULK COLLECT INTO recordVariable limit 2;
EXIT WHEN recordVariable.column1.COUNT = 0;
FORALL forIndex IN recordVariable.column1.FIRST..recordVariable.column1.LAST
INSERT INTO table2 (column1, column2)
VALUES (recordVariable.column1(forIndex), recordVariable.column2(forIndex));
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "table1", "table2" **
CREATE OR REPLACE PROCEDURE myProcedure ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
cursorVariable OBJECT := INIT_CURSOR_UDF('cursorVariable', ' SELECT * FROM
table1');
!!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
TYPE columnsRecordType IS RECORD (column1 dbms_sql.NUMBER_table, column2 dbms_sql.NUMBER_table);
recordVariable OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - columnsRecordType DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'collectionTypeDefinition' USAGE CHANGED TO VARIANT ***/!!!;
col1 VARIANT /*** SSC-FDM-0015 - REFERENCED CUSTOM TYPE 'dbms_sql.NUMBER_table' IN QUERY NOT FOUND, USAGES MAY BE AFFECTED ***/;
col2 VARIANT /*** SSC-FDM-0015 - REFERENCED CUSTOM TYPE 'dbms_sql.NUMBER_table' IN QUERY NOT FOUND, USAGES MAY BE AFFECTED ***/;
FORALL INTEGER;
BEGIN
cursorVariable := (
CALL OPEN_BULK_CURSOR_UDF(:cursorVariable)
);
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
cursorVariable := (
CALL FETCH_BULK_COLLECTION_RECORDS_UDF(:cursorVariable, 2)
);
collectionVariable := :cursorVariable:RESULT;
FORALL := ARRAY_SIZE(:collectionVariable);
INSERT INTO table2(column1, column2)
(
SELECT
:collectionVariable[forIndex]:column1,
: collectionVariable[forIndex]:column2
FROM
(
SELECT
seq4() AS forIndex
FROM
TABLE(GENERATOR(ROWCOUNT => :FORALL))
)
);
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
cursorVariable := (
CALL FETCH_BULK_COLLECTIONS_UDF(:cursorVariable, 2)
);
col1 := :cursorVariable:RESULT[0];
col2 := :cursorVariable:RESULT[1];
FORALL := ARRAY_SIZE(:col1);
INSERT INTO table2(column1, column2)
(
SELECT
:col1[forIndex],
: col2[forIndex]
FROM
(
SELECT
seq4() AS forIndex
FROM
TABLE(GENERATOR(ROWCOUNT => :FORALL))
)
);
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
cursorVariable := (
CALL FETCH_BULK_RECORD_COLLECTIONS_UDF(:cursorVariable, 2)
);
recordVariable := :cursorVariable:RESULT;
IF (ARRAY_SIZE(:recordVariable:column1) = 0) THEN
EXIT;
END IF;
FORALL := ARRAY_SIZE(:recordVariable:column1);
INSERT INTO table2(column1, column2)
(
SELECT
:recordVariable:column1[forIndex],
: recordVariable:column2[forIndex]
FROM
(
SELECT
seq4() AS forIndex
FROM
TABLE(GENERATOR(ROWCOUNT => :FORALL))
)
);
END LOOP;
cursorVariable := (
CALL CLOSE_BULK_CURSOR_UDF(:cursorVariable)
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
Note
Cette transformation n’est effectuée que lorsqu’aucune des transformations mentionnées précédemment ne peut être réalisée.
14. Multiple FORALL inside a LOOP clause¶
Note
Ce modèle s’applique lorsqu’il y a plus d’un FORALL dans la même procédure et qu’il répond à la structure suivante.
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 20;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
UPDATE table2 SET column1 = '54321' WHERE column2 = collectionVariable(forIndex).column2;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
* FROM
table1
);
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column1 = '54321'
FROM
(
SELECT
* FROM
table1) AS collectionVariable
WHERE
column2 = collectionVariable.column2;
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
15. Multiple FORALL inside different LOOP clauses¶
Note
Ce modèle s’applique lorsqu’il y a plus d’un FORALL dans la même procédure et qu’il répond à la structure suivante.
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
CURSOR cursorVariable2 IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
TYPE collectionTypeDefinition2 IS
TABLE OF table1%ROWTYPE;
collectionVariable2 collectionTypeDefinition2;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
END LOOP;
CLOSE cursorVariable;
OPEN cursorVariable2;
LOOP
FETCH cursorVariable2 BULK COLLECT INTO collectionVariable2 limit 2;
EXIT WHEN collectionVariable2.COUNT = 0;
FORALL forIndex IN collectionVariable2.FIRST..collectionVariable2.LAST
UPDATE table2 SET column1 = '54321' WHERE column2 = collectionVariable2(forIndex).column2;
END LOOP;
CLOSE cursorVariable2;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
* FROM
table1
);
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column1 = '54321'
FROM
(
SELECT
* FROM
table1) AS collectionVariable2
WHERE
column2 = collectionVariable2.column2;
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
16. FORALL with MERGE INTO with LOG ERRORS¶
Avertissement
Ce modèle n’est pas encore mis en œuvre
Oracle¶
LOG ERRORS¶
CREATE OR REPLACE PROCEDURE procedure_example (
department_id_in IN source_table.DepartmentID%TYPE)
IS
TYPE employee_ids_t IS TABLE OF source_table%ROWTYPE
INDEX BY PLS_INTEGER;
employee_list employee_ids_t;
BEGIN
SELECT *
BULK COLLECT INTO employee_list
FROM source_table
WHERE DepartmentID = procedure_example.department_id_in;
FORALL indx IN 1 .. employee_list.COUNT
MERGE INTO target_table
USING (SELECT * FROM DUAL) src
ON (id = employee_list(indx).id)
WHEN MATCHED THEN
UPDATE SET
name = employee_list(indx).Name
WHEN NOT MATCHED THEN
INSERT (Id, Name, DepartmentID)
VALUES (employee_list(indx).Id, employee_list(indx).Name, employee_list(indx).DepartmentID)
LOG ERRORS INTO error_table('MERGE INTO ERROR')
REJECT LIMIT UNLIMITED;
END;
CALL procedure_example(10);
select * from target_table;
select * from error_table;
Snowflake¶
LOG ERRORS¶
--Generated by SnowConvert---------------
CREATE OR REPLACE TRANSIENT TABLE target_staging_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
--Generated by SnowConvert---------------
CREATE OR REPLACE PROCEDURE procedure_example (DEPARTMENT_ID_IN INT !!!RESOLVE EWI!!! /*** SSC-EWI-OR0129 - TYPE ATTRIBUTE 'source_table.DepartmentID%TYPE' COULD NOT BE RESOLVED, SO IT WAS TRANSFORMED TO VARIANT ***/!!!)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CREATE OR REPLACE TEMP TABLE SOURCE_TEMPORAL AS
WITH source_data as (
SELECT *
FROM source_table
WHERE DEPARTMENTID =: DEPARTMENT_ID_IN
)
SELECT source_data.*, parent_table.id as PARENT_KEY
FROM source_data
left join parent_table on source_data.DepartmentID = parent_table.id;
--All records violating foreign key integrity
INSERT INTO error_table (ERROR, COLUMN_NAME, REJECTED_RECORD)
SELECT
'Foreign Key Constraint Violated' ERROR,'KEY_COL' COLUMN_NAME, id
FROM SOURCE_TEMPORAL
WHERE PARENT_KEY IS NULL;
DELETE FROM SOURCE_TEMPORAL
WHERE PARENT_KEY IS NULL;
BEGIN
MERGE INTO target_table
USING SOURCE_TEMPORAL SRC
ON SRC.id = target_table.id
WHEN MATCHED THEN
UPDATE SET
name = SRC.name
WHEN NOT MATCHED THEN
INSERT (Id, Name, DepartmentID)
VALUES (SRC.Id, SRC.Name, SRC.DepartmentID);
EXCEPTION
WHEN OTHER THEN
CREATE OR REPLACE TEMPORARY STAGE my_int_stage
COPY_OPTIONS = (ON_ERROR='continue');
--Create my file and populate with data
COPY INTO @my_int_stage/my_file FROM (
SELECT * exclude(PARENT_KEY) FROM SOURCE_TEMPORAL
) OVERWRITE = TRUE ;
COPY INTO target_staging_table(id, name, DepartmentID)
FROM (
SELECT
-- distinct
t.$1, t.$2, t.$3
FROM @my_int_stage/my_file t
) ON_ERROR = CONTINUE;
INSERT INTO ERROR_TABLE (ERROR, FILE, LINE, CHARACTER, CATEGORY, CODE, SQL_STATE, COLUMN_NAME, ROW_NUMBER, REJECTED_RECORD)
SELECT
ERROR, FILE,LINE, CHARACTER, CATEGORY, CODE, SQL_STATE, COLUMN_NAME, ROW_NUMBER, REJECTED_RECORD
FROM TABLE(VALIDATE(target_staging_table, JOB_ID => '_last')) order by line; --The last charge on the current session
MERGE INTO target_table
USING target_staging_table staging
ON staging.id = target_table.id
WHEN MATCHED THEN
UPDATE SET
name = staging.name
WHEN NOT MATCHED THEN
INSERT (Id, Name, DepartmentID)
VALUES (staging.Id, staging.Name, staging.DepartmentID);
END;
return 'Awesome!';
END;
$$;
CALL procedure_example(10);
SELECT * FROM target_table;
SELECT * FROM error_table;
17. FORALL with INSERT with LOG ERRORS¶
Avertissement
Ce modèle n’est pas encore mis en œuvre
Oracle¶
LOG ERRORS¶
CREATE OR REPLACE PROCEDURE procedure_example (
department_id_in IN source_table.DepartmentID%TYPE)
IS
TYPE employee_ids_t IS TABLE OF source_table%ROWTYPE
INDEX BY PLS_INTEGER;
employee_list employee_ids_t;
BEGIN
SELECT *
BULK COLLECT INTO employee_list
FROM source_table
WHERE DepartmentID = procedure_example.department_id_in;
FORALL indx IN 1 .. employee_list.COUNT
INSERT INTO target_table(Id, Name, DepartmentID)
VALUES (employee_list(indx).Id, employee_list(indx).Name, employee_list(indx).DepartmentID)
LOG ERRORS INTO error_table('MERGE INTO ERROR')
REJECT LIMIT UNLIMITED;
END;
Snowflake¶
LOG ERRORS¶
--Generated by SnowConvert---------------
CREATE OR REPLACE TRANSIENT TABLE target_staging_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
--Generated by SnowConvert---------------
CREATE OR REPLACE PROCEDURE procedure_example (DEPARTMENT_ID_IN INT !!!RESOLVE EWI!!! /*** SSC-EWI-OR0129 - TYPE ATTRIBUTE 'employees.DepartmentID%TYPE' COULD NOT BE RESOLVED, SO IT WAS TRANSFORMED TO VARIANT ***/!!!)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CREATE OR REPLACE TEMP TABLE SOURCE_TEMPORAL AS
WITH source_data as (
SELECT *
FROM source_table
WHERE DEPARTMENTID =: DEPARTMENT_ID_IN
)
SELECT source_data.*, parent_table.id as PARENT_KEY
FROM source_data
left join parent_table on source_data.DepartmentID = parent_table.id;
--All records violating foreign key integrity
INSERT INTO error_table (ERROR, COLUMN_NAME, REJECTED_RECORD)
SELECT
'Foreign Key Constraint Violated' ERROR,'KEY_COL' COLUMN_NAME, id
FROM SOURCE_TEMPORAL
WHERE PARENT_KEY IS NULL;
DELETE FROM SOURCE_TEMPORAL
WHERE PARENT_KEY IS NULL;
BEGIN
INSERT INTO target_table (Id, Name, DepartmentID)
SELECT SRC.Id, SRC.Name, SRC.DepartmentID FROM SOURCE_TEMPORAL SRC;
EXCEPTION
WHEN OTHER THEN
CREATE OR REPLACE TEMPORARY STAGE my_int_stage
COPY_OPTIONS = (ON_ERROR='continue');
--Create my file and populate with data
COPY INTO @my_int_stage/my_file FROM (
SELECT * exclude(PARENT_KEY) FROM SOURCE_TEMPORAL
) OVERWRITE = TRUE ;
COPY INTO target_staging_table(id, name, DepartmentID)
FROM (
SELECT
-- distinct
t.$1, t.$2, t.$3
FROM @my_int_stage/my_file t
) ON_ERROR = CONTINUE;
INSERT INTO ERROR_TABLE (ERROR, FILE, LINE, CHARACTER, CATEGORY, CODE, SQL_STATE, COLUMN_NAME, ROW_NUMBER, REJECTED_RECORD)
SELECT
ERROR, FILE,LINE, CHARACTER, CATEGORY, CODE, SQL_STATE, COLUMN_NAME, ROW_NUMBER, REJECTED_RECORD
FROM TABLE(VALIDATE(target_staging_table, JOB_ID => '_last')) order by line; --The last charge on the current session
INSERT INTO target_table (Id, Name, DepartmentID)
SELECT staging.Id, staging.Name, staging.DepartmentID FROM target_staging_table staging;
END;
END;
$$;
CALL procedure_example(10);
SELECT * FROM target_table;
SELECT * FROM error_table;
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
SSC-EWI-0030: L’instruction ci-dessous a des utilisations de Dynamic SQL.
SSC-EWI-0036 : Type de données converti en un autre type de données.
SSC-EWI-0056 : Create table n’est pas pris en charge.
SSC-EWI-0058: La fonctionnalité n’est pas prise en charge actuellement par Snowflake Scripting.
SSC-EWI-0062: L’utilisation du type personnalisé a changé en variante.
SSC-EWI-OR0049: Les constantes de paquet dans le paquet avec état ne sont pas encore prises en charge.
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-FDM-0015: Type personnalisé référencé dans la requête introuvable.
SSC-PRF-0001: Cette instruction a des utilisations des opérations en masse de curseur Fetch.
SSC-PRF-0003: Fetch à l’intérieur d’une boucle est considéré comme un modèle complexe, cela pourrait dégrader les performances de Snowflake.
IF¶
Description¶
L’instruction IF permet d’exécuter ou d’ignorer une séquence d’une ou plusieurs instructions, en fonction de la valeur d’une expression BOOLEAN. Pour plus d’informations sur Oracle IF, cliquez ici.
IF boolean_expression THEN
statement
[ statement ]...
[
ELSIF boolean_expression THEN
statement
[ statement ]... ]...
[
ELSE
statement [ statement ]... ] END IF ;
IF ( <condition> ) THEN
<statement>;
[ <statement>; ... ]
[
ELSEIF ( <condition> ) THEN
<statement>;
[ <statement>; ... ]
]
[
ELSE
<statement>;
[ <statement>; ... ]
]
END IF;
Modèles d’échantillons de sources¶
Échantillon de table auxiliaire¶
CREATE TABLE if_table(col1 varchar(30));
CREATE OR REPLACE TABLE PUBLIC.if_table (col1 varchar(30));
Variantes possibles de IF¶
Oracle¶
Code 1¶
CREATE OR REPLACE PROCEDURE ifExample1 ( flag NUMBER )
IS
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
END IF;
END;
CALL ifExample1(1);
SELECT * FROM if_table;
Code 2¶
CREATE OR REPLACE PROCEDURE ifExample2 ( flag NUMBER )
IS
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
CALL ifExample2(2);
SELECT * FROM if_table;
Code 3¶
CREATE OR REPLACE PROCEDURE ifExample3 ( flag NUMBER )
IS
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSIF flag = 2 THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSIF flag = 3 THEN
INSERT INTO if_table(col1) VALUES ('three');
END IF;
END;
CALL ifExample3(3);
SELECT * FROM if_table;
Code 4¶
CREATE OR REPLACE PROCEDURE ifExample4 ( flag NUMBER )
IS
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSIF flag = 2 THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSIF flag = 3 THEN
INSERT INTO if_table(col1) VALUES ('three');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
CALL ifExample4(4);
SELECT * FROM if_table;
Résultat 1¶
COL1 |
|---|
un |
Résultat 2¶
COL1 |
|---|
Entrée inattendue. |
Résultat 3¶
COL1 |
|---|
trois |
Résultat 4¶
COL1 |
|---|
Entrée inattendue. |
Exécution de scripts Snowflake¶
Code 1¶
CREATE OR REPLACE PROCEDURE ifExample1 (flag NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (:flag = 1) THEN
INSERT INTO if_table(col1) VALUES ('one');
END IF;
END;
$$;
CALL ifExample1(1);
SELECT * FROM
if_table;
Code 2¶
CREATE OR REPLACE PROCEDURE ifExample2 (flag NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (:flag = 1) THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
$$;
CALL ifExample2(2);
SELECT * FROM
if_table;
Code 3¶
CREATE OR REPLACE PROCEDURE ifExample3 (flag NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (:flag = 1) THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSEIF (:flag = 2) THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSEIF (:flag = 3) THEN
INSERT INTO if_table(col1) VALUES ('three');
END IF;
END;
$$;
CALL ifExample3(3);
SELECT * FROM
if_table;
Code 4¶
CREATE OR REPLACE PROCEDURE ifExample4 (flag NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (:flag = 1) THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSEIF (:flag = 2) THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSEIF (:flag = 3) THEN
INSERT INTO if_table(col1) VALUES ('three');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
$$;
CALL ifExample4(4);
SELECT * FROM if_table;
Résultat 1¶
COL1 |
|---|
un |
Résultat 2¶
COL1 |
|---|
Entrée inattendue. |
Résultat 3¶
COL1 |
|---|
trois |
Résultat 4¶
COL1 |
|---|
Entrée inattendue. |
Problèmes connus¶
Aucun problème n’a été constaté.
connexesEWIS¶
Pas d’EWIs connexes.
IS EMPTY¶
Il s’agit d’une référence de traduction pour convertir l’instruction IS EMPTY Oracle en instruction Snowflake
Avertissement
Les informations de cette section, en cours de modification, sont sujettes à modification.
Description¶
Utilisez les conditions IS [[NOT] EMPTY pour vérifier si une table imbriquée spécifiée est vide, que des éléments de la collection soient ou non NULL. (Documentation.)
Syntaxe Oracle¶
nested_table IS [ NOT ] EMPTY
Modèles d’échantillons de sources¶
Oracle¶
L’exemple suivant illustre l’utilisation de l’instruction IS EMPTY. L’instruction est appliquée à une table imbriquée dont le type de définition est UDT. La sortie indique le nom des employés qui n’ont pas de numéro de téléphone.
CREATE TYPE phone_number_type AS OBJECT (phone_number VARCHAR2(30));
/
CREATE TYPE phone_number_list AS TABLE OF phone_number_type;
CREATE TABLE employee (
emp_id NUMBER,
emp_name VARCHAR2(50),
phone_numbers_col phone_number_list
) NESTED TABLE phone_numbers_col STORE AS nested_tab return as value;
INSERT INTO employee VALUES (
1,
'John Doe',
phone_number_list(phone_number_type('1234567890'))
);
/
INSERT INTO employee VALUES (
2,
'Jane Smith',
phone_number_list()
);
SELECT emp_name
FROM employee
WHERE phone_numbers_col IS EMPTY;
Sortie¶
EMP_NAME |
|---|
Jane Smith |
Snowflake¶
La requête Snowflake présentée ci-dessous est l’équivalence de la fonctionnalité de l’instruction IS EMPTY. En particulier, l’instruction IS EMPTY fait la différence entre un objet NULL et un objet EMPTY.
Remarquez que les types définis par l’utilisateur sont transformés en VARIANT. Le type VARIANT dans Snowflake permet de stocker des objets et des tableaux. Comme une table imbriquée est une séquence d’informations, le type ARRAY est le type le plus approprié pour les redéfinir et vérifier si l’objet ARRAY est vide.
La solution équivalente ARRAY_SIZE permet également de demander la nullité de la table imbriquée (transformée en VARIANT). En d’autres termes, le type VARIANT peut également stocker des NULLs et des ARRAYs vides.
!!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO VARIANT ***/!!!
CREATE TYPE phone_number_type AS OBJECT (phone_number VARCHAR2(30))
;
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NESTED TABLE' NODE ***/!!!
CREATE TYPE phone_number_list AS TABLE OF phone_number_type;
CREATE OR REPLACE TABLE employee (
emp_id NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
emp_name VARCHAR(50),
phone_numbers_col VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'phone_number_list' USAGE CHANGED TO VARIANT ***/!!!
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE VIEW PUBLIC.employee_view
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "" }}'
AS
SELECT
emp_id,
emp_name,
phone_numbers_col
FROM
employee;
INSERT INTO employee
VALUES (
1,
'John Doe',
phone_number_list(phone_number_type('1234567890') !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'phone_number_type' NODE ***/!!!) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'phone_number_list' NODE ***/!!!
);
INSERT INTO employee
VALUES (
2,
'Jane Smith',
phone_number_list() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'phone_number_list' NODE ***/!!!
);
SELECT emp_name
FROM
employee
WHERE
ARRAY_SIZE( phone_numbers_col) = 0;
Sortie¶
EMP_NAME |
|---|
Jane Smith |
Autres combinaisons possibles¶
| Description | Oracle | Snowflake |
|---|---|---|
| Ask for a IS NOT EMPTY | | |
| Ask for NULL instead of EMPTY | | |
Problèmes connus¶
1. Les types définis par l’utilisateur sont en cours de transformation en types de variantes.¶
Les types définis par l’utilisateur ne sont pas pris en charge et sont donc transformés en types de variantes, ce qui peut nécessiter un effort manuel pour garantir certaines fonctions.
Consultez la page suivante pour plus d’informations :
**2. Les tables imbriquées ne sont pas prises en charge.¶
Les tables imbriquées ne sont pas prises en charge actuellement. La meilleure approche sur la base de cette équivalence consiste à traiter les tables imbriquées comme des variantes, mais à déclarer des tableaux contenant des données JSON et à exécuter la fonction PARSE_JSON Snowflake pour remplir les informations imbriquées.
Consultez les pages suivantes pour plus d’informations :
3. Les instructions d’insertion ne sont pas prises en charge pour les types définis par l’utilisateur.¶
Les types définis par l’utilisateur n’étant pas pris en charge, les instructions d’insertion dans ces types ne sont pas prises en charge. Dans les tables imbriquées, l’instruction INSERT INTO ... VALUES doit être remplacée par INSERT INTO...SELECT, car la fonction ARRAY_CONSTRUCT est censée être utilisée dans ce modèle.
Consultez la page suivante pour plus d’informations :
4. La logique doit être adaptée aux types ARRAY.¶
Comme les tables imbriquées doivent être transformées de manière équivalente à VARIANT et se comporter comme ARRAYs,, la fonctionnalité et la logique de mise en œuvre des procédures et d’interaction avec les données doivent être adaptées.
Examinez les exemples suivants :
4.1 Équivalence des procédures¶
Oracle¶
create or replace procedure proc1
as
col1 phone_number_list:= phone_number_list();
begin
IF col1 IS EMPTY
THEN
dbms_output.put_line('IS EMPTY');
END IF;
end;
Snowflake¶
CREATE OR REPLACE PROCEDURE proc1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
col1 VARIANT /*** SSC-FDM-0015 - REFERENCED CUSTOM TYPE 'phone_number_list' IN QUERY NOT FOUND, USAGES MAY BE AFFECTED ***/ := phone_number_list() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'phone_number_list' NODE ***/!!!;
BEGIN
IF (ARRAY_SIZE(:col1) = 0) THEN
--** SSC-FDM-OR0035 - CHECK UDF IMPLEMENTATION FOR DBMS_OUTPUT.PUT_LINE_UDF. **
CALL DBMS_OUTPUT.PUT_LINE_UDF('IS EMPTY');
END IF;
END;
$$;
Sortie¶
PROC1 |
|---|
IS EMPTY |
4.2 Instructions de sélection¶
Les sorties peuvent différer d’une table à l’autre sur les ARRAYs.
Oracle¶
SELECT
t.*
FROM
employee e,
table(e.phone_numbers_col) t
WHERE
emp_id = 1;
Sortie¶
PHONE_NUMBER |
|---|
1234567890 |
Snowflake¶
SELECT
t.*
FROM
employee e,
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0035 - TABLE FUNCTION IS NOT SUPPORTED WHEN IT IS USED AS A COLLECTION OF EXPRESSIONS ***/!!!
table(e.phone_numbers_col) t
WHERE
emp_id = 1;
Sortie¶
PHONE_NUMBERS_COL |
|---|
[ 1234567890 ] |
EWIs connexes¶
SSC-EWI-0056 : Create table n’est pas pris en charge.
SSC-EWI-0062: L’utilisation du type personnalisé a changé en variante.
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-EWI-OR0035: La fonction de table n’est pas prise en charge lorsqu’elle est utilisée sous la forme d’un ensemble d’expressions.
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-FDM-0015: Type personnalisé référencé dans la requête introuvable.
SSC-FDM-OR0035: DBMS_OUTPUT.PUTLINE consultez l’implémentation UDF.
LOCK TABLE¶
Note
Instruction non pertinente.
Avertissement
Notez que cette instruction a été supprimée de la migration ; car la syntaxe n’est pas pertinente. Cela signifie qu’elle n’est pas requise dans Snowflake.
Description¶
Dans Oracle, l’instruction LOCK TABLE permet d’acquérir explicitement un verrou de table partagé ou exclusif sur la table spécifiée. Le verrou de table dure jusqu’à la fin de la transaction en cours. Pour plus d’informations, cliquez ici.
Syntaxe
LOCK TABLE tableName IN { SHARE | EXCLUSIVE } MODE
Modèles d’échantillons de sources¶
Table verrouillée¶
Notez que dans cet exemple, l’instruction LOCK TABLE a été supprimée. En effet, Snowflake gère le verrouillage d’une manière différente, par le biais de transactions.
Oracle¶
LOCK TABLE table1 IN EXCLUSIVE MODE;
Snowflake¶
[Empty output]
LOG ERROR¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
L’instruction
FORALLexécute une instruction DML plusieurs fois, avec des valeurs différentes dans les clausesVALUESetWHERE. (Référence linguistique Oracle PL/SQL Instruction FORALL).
Syntaxe Oracle¶
FORALL index IN bounds_clause [ SAVE ] [ EXCEPTIONS ] dml_statement ;
Avertissement
Snowflake Scripting n’a pas d’équivalence directe avec l’instruction FORALL, mais peut être émulé avec différentes solutions de contournement pour obtenir une équivalence fonctionnelle.
Modèles d’échantillons de sources¶
Données de configuration¶
Oracle¶
Tables¶
CREATE TABLE error_table (
ORA_ERR_NUMBER$ NUMBER,
ORA_ERR_MESG$ VARCHAR2(2000),
ORA_ERR_ROWID$ ROWID,
ORA_ERR_OPTYP$ VARCHAR2(2),
ORA_ERR_TAG$ VARCHAR2(2000)
);
--departments
CREATE TABLE parent_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10)
);
INSERT INTO parent_table VALUES (10, 'IT');
INSERT INTO parent_table VALUES (20, 'HR');
INSERT INTO parent_table VALUES (30, 'INFRA');
--employees
CREATE TABLE source_table(
Id INT PRIMARY KEY,
Name VARCHAR2(20) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
);
INSERT INTO source_table VALUES (101, 'Anurag111111111', 10);
INSERT INTO source_table VALUES (102, 'Pranaya11111111', 20);
INSERT INTO source_table VALUES (103, 'Hina11111111111', 30);
--a copy of source
CREATE TABLE target_table(
Id INT PRIMARY KEY,
Name VARCHAR2(10) NOT NULL,
DepartmentID INT REFERENCES parent_table(Id)
);
INSERT INTO target_table VALUES (101, 'Anurag', 10);
Snowflake¶
Tables¶
CREATE OR REPLACE TABLE error_table (
"ORA_ERR_NUMBER$" NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
"ORA_ERR_MESG$" VARCHAR(2000),
"ORA_ERR_ROWID$" VARCHAR(18) !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - ROWID DATA TYPE CONVERTED TO VARCHAR ***/!!!,
"ORA_ERR_OPTYP$" VARCHAR(2),
"ORA_ERR_TAG$" VARCHAR(2000)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
--departments
CREATE OR REPLACE TABLE parent_table (
Id INT PRIMARY KEY,
Name VARCHAR(10)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO parent_table
VALUES (10, 'IT');
INSERT INTO parent_table
VALUES (20, 'HR');
INSERT INTO parent_table
VALUES (30, 'INFRA');
--employees
CREATE OR REPLACE TABLE source_table (
Id INT PRIMARY KEY,
Name VARCHAR(20) NOT NULL,
DepartmentID INT REFERENCES parent_table (Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO source_table
VALUES (101, 'Anurag111111111', 10);
INSERT INTO source_table
VALUES (102, 'Pranaya11111111', 20);
INSERT INTO source_table
VALUES (103, 'Hina11111111111', 30);
--a copy of source
CREATE OR REPLACE TABLE target_table (
Id INT PRIMARY KEY,
Name VARCHAR(10) NOT NULL,
DepartmentID INT REFERENCES parent_table (Id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
INSERT INTO target_table
VALUES (101, 'Anurag', 10);
1. MERGE INTO Inside a FORALL¶
Oracle¶
Remarque
Les trois cas ci-dessous ont la même transformation en Snowflake Scripting et sont fonctionnellement équivalents.
Cas 1.¶
CREATE OR REPLACE PROCEDURE procedure_example (
department_id_in IN source_table.DepartmentID%TYPE)
IS
TYPE employee_ids_t IS TABLE OF source_table%ROWTYPE
INDEX BY PLS_INTEGER;
employee_list employee_ids_t;
BEGIN
SELECT *
BULK COLLECT INTO employee_list
FROM source_table
WHERE DepartmentID = procedure_example.department_id_in;
FORALL indx IN 1 .. employee_list.COUNT
MERGE INTO target_table
USING (SELECT * FROM DUAL) src
ON (id = employee_list(indx).id)
WHEN MATCHED THEN
UPDATE SET
name = employee_list(indx).Name
WHEN NOT MATCHED THEN
INSERT (Id, Name, DepartmentID)
VALUES (employee_list(indx).Id, employee_list(indx).Name, employee_list(indx).DepartmentID)
LOG ERRORS INTO error_table('MERGE INTO ERROR')
REJECT LIMIT UNLIMITED;
END;
CALL procedure_example(10);
select * from target_table;
select * from error_table;
Snowflake¶
FORALL avec collection d’enregistrements¶
CREATE OR REPLACE PROCEDURE procedure_example (department_id_in VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-OR0129 - TYPE ATTRIBUTE 'source_table.DepartmentID%TYPE' COULD NOT BE RESOLVED, SO IT WAS TRANSFORMED TO VARIANT ***/!!!)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'PL COLLECTION TYPE DEFINITION' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- TYPE employee_ids_t IS TABLE OF source_table%ROWTYPE
-- INDEX BY PLS_INTEGER;
employee_list VARIANT !!!RESOLVE EWI!!! /*** SSC-EWI-0062 - CUSTOM TYPE 'employee_ids_t' USAGE CHANGED TO VARIANT ***/!!!;
FORALL INTEGER;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'RECORDS AND COLLECTIONS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
SELECT *
BULK COLLECT INTO employee_list
FROM source_table
WHERE DepartmentID = procedure_example.department_id_in;
FORALL := ARRAY_SIZE(:employee_list);
MERGE INTO target_table
USING (SELECT * FROM
(
SELECT
seq4() AS indx
FROM
TABLE(GENERATOR(ROWCOUNT => :FORALL))
)) src
ON (id = : employee_list[indx]:id)
WHEN MATCHED THEN
UPDATE SET
name = : employee_list[indx]:Name
WHEN NOT MATCHED THEN
INSERT (Id, Name, DepartmentID)
VALUES (:employee_list[indx]:Id, : employee_list[indx]:Name, : employee_list[indx]:DepartmentID)
-- --** SSC-FDM-OR0031 - THE ERROR LOGGING CLAUSE IN DML STATEMENTS IS NOT SUPPORTED BY SNOWFLAKE **
-- LOG ERRORS INTO error_table('MERGE INTO ERROR')
-- REJECT LIMIT UNLIMITED
;
END;
$$;
CALL procedure_example(10);
select * from
target_table;
select * from
error_table;
2. FORALL With INSERT INTO¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
* FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
3. FORALL With Multiple Fetched Collections¶
Oracle¶
Avec INSERT INTO¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
column1Collection dbms_sql.NUMBER_table;
column2Collection dbms_sql.NUMBER_table;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO column1Collection, column2Collection limit 20;
EXIT WHEN column1Collection.COUNT = 0;
FORALL forIndex IN 1..column1Collection.COUNT
INSERT INTO table2 VALUES (
column1Collection(forIndex),
column2Collection(forIndex)
);
END LOOP;
CLOSE cursorVariable;
END;
Avec UPDATE¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
column1Collection dbms_sql.NUMBER_table;
column2Collection dbms_sql.NUMBER_table;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO column1Collection, column2Collection limit 2;
EXIT WHEN column1Collection.COUNT = 0;
FORALL forIndex IN 1..column1Collection.COUNT
UPDATE table2 SET column2 = column2Collection(forIndex)
WHERE column1 = column1Collection(forIndex);
END LOOP;
CLOSE cursorVariable;
END;
Résultats INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
1 |
2 |
Résultats UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
Snowflake¶
Avec INSERT INTO¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
$1,
$2
FROM
table1
);
END;
$$;
Avec UPDATE¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column2 = column1Collection.$2
FROM
(
SELECT
* FROM
table1) AS column1Collection
WHERE
column1 = column1Collection.$1;
END;
$$;
Résultats INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
Résultats UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
4. FORALL With Record of Collections¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE recordType IS RECORD(
column1Collection dbms_sql.NUMBER_table,
column2Collection dbms_sql.NUMBER_table
);
columnRecord recordType;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO columnRecord.column1Collection, columnRecord.column2Collection limit 20;
FORALL forIndex IN 1..columnRecord.column1Collection.COUNT
INSERT INTO table2 VALUES (
columnRecord.column1Collection(forIndex),
columnRecord.column2Collection(forIndex)
);
EXIT WHEN cursorVariable%NOTFOUND;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL Scripting¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
$1,
$2
FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
5. FORALL With Dynamic SQL¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
cursorVariable SYS_REFCURSOR;
TYPE collectionTypeDefinition IS
TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
query VARCHAR(200) := 'SELECT * FROM table1';
BEGIN
OPEN cursorVariable FOR query;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
INSERT INTO table2 VALUES collectionVariable(forIndex);
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
query VARCHAR(200) := 'SELECT * FROM
table1';
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'CREATE OR REPLACE TEMPORARY TABLE query AS ' || :query;
INSERT INTO table2
(
SELECT
*
FROM
query
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000 |
6. FORALL Without LOOPS¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
SELECT * BULK COLLECT INTO collectionVariable FROM table1;
FORALL forIndex IN 1..collectionVariable.COUNT
INSERT INTO table2 VALUES (
collectionVariable (forIndex).column1,
collectionVariable (forIndex).column2
);
collectionVariable.DELETE;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
INSERT INTO table2
(
SELECT
column1,
column2
FROM
table1
);
END;
$$;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
1.000000000000000000 |
2.000000000000000000 |
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
7. FORALL With UPDATE Statements¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
UPDATE table2 SET column1 = '54321' WHERE column2 = collectionVariable(forIndex).column2;
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
UPDATE table2
SET column1 = '54321'
FROM
(
SELECT
* FROM
table1) AS collectionVariable
WHERE
column2 = collectionVariable.column2;
END;
$$;
Résultats¶
ambiguous column name 'COLUMN2'
8. FORALL With DELETE Statements¶
Oracle¶
Exemple FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure IS
CURSOR cursorVariable IS
SELECT * FROM table1;
TYPE collectionTypeDefinition IS TABLE OF table1%ROWTYPE;
collectionVariable collectionTypeDefinition;
BEGIN
OPEN cursorVariable;
LOOP
FETCH cursorVariable BULK COLLECT INTO collectionVariable limit 2;
EXIT WHEN collectionVariable.COUNT = 0;
FORALL forIndex IN collectionVariable.FIRST..collectionVariable.LAST
DELETE FROM table2 WHERE column2 = collectionVariable(forIndex).column2;
collectionVariable.DELETE;
END LOOP;
CLOSE cursorVariable;
END;
Résultats¶
no data found
Snowflake¶
Équivalent FORALL¶
CREATE OR REPLACE PROCEDURE myProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
--** SSC-PRF-0001 - THIS STATEMENT HAS USAGES OF CURSOR FETCH BULK OPERATIONS **
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
DELETE FROM
table2
USING (
SELECT
* FROM
table1) collectionVariable
WHERE
table2.column2 = collectionVariable.column2;
END;
$$;
Résultats¶
Query produced no results
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
SSC-EWI-0030: L’instruction ci-dessous a des utilisations de Dynamic SQL.
SSC-EWI-0036 : Type de données converti en un autre type de données.
SSC-EWI-0058: La fonctionnalité n’est pas prise en charge actuellement par Snowflake Scripting.
SSC-EWI-0062: L’utilisation du type personnalisé a changé en variante.
SSC-EWI-OR0129: TYPE L’attribut n’a pas pu être résolu.
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-FDM-OR0031: L’erreur de clause de journalisation dans les instructions DML n’est pas prise en charge par Snowflake.
SSC-PRF-0001: Cette instruction a des utilisations des opérations en masse de curseur Fetch.
SSC-PRF-0003: Fetch à l’intérieur d’une boucle est considéré comme un modèle complexe, cela pourrait dégrader les performances de Snowflake.
LOOP¶
Référence de traduction pour convertir l’instruction Oracle LOOP en instruction Snowflake Scripting
Description¶
Avec chaque itération de l’instruction de base
LOOP, ses instructions s’exécutent et contrôlent les retours en haut de la boucle. L’instructionLOOPse termine lorsqu’une instruction à l’intérieur de la boucle transfère le contrôle en dehors de la boucle ou lève une exception.\ (Référence linguistique Oracle PL/SQL Instruction BASIC LOOP).
Syntaxe BASIC LOOP Oracle¶
LOOP statement... END LOOP [ label ] ;
Syntaxe BASIC LOOP Snowflake Scripting¶
LOOP
<statement>;
[ <statement>; ... ]
END LOOP [ <label> ] ;
Le comportement d’Oracle BASIC LOOP peut également être modifié à l’aide des instructions :
Modèles d’échantillons de sources¶
Cas simple de Loop¶
Remarque
Ce cas est équivalent sur le plan fonctionnel.
Oracle¶
CREATE TABLE loop_testing_table
(
iterator VARCHAR2(5)
);
CREATE OR REPLACE PROCEDURE loop_procedure
IS
I NUMBER := 1;
J NUMBER := 10;
BEGIN
LOOP
EXIT WHEN I = J;
INSERT INTO loop_testing_table VALUES(TO_CHAR(I));
I := I+1;
END LOOP;
END;
CALL loop_procedure();
SELECT * FROM loop_testing_table;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE loop_testing_table
(
iterator VARCHAR(5)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
;
CREATE OR REPLACE PROCEDURE loop_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 1;
J NUMBER(38, 18) := 10;
BEGIN
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
IF (:I = :J) THEN
EXIT;
END IF;
INSERT INTO loop_testing_table
VALUES(TO_CHAR(:I));
I := :I +1;
END LOOP;
END;
$$;
CALL loop_procedure();
SELECT * FROM
loop_testing_table;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
Pas d’EWIs connexes.
OUTPUT PARAMETERS¶
Description¶
Un paramètre de sortie est un paramètre dont la valeur est transmise à l’extérieur du module de procédure stockée/fonction, vers le bloc appelant PL/SQL. Les paramètres de sortie n’étant pas pris en charge par le support Snowflake Scripting, une solution a été mise en œuvre afin d’émuler leur fonctionnalité.
Modèles d’échantillons de sources¶
Paramètre unique Out¶
Oracle¶
-- Procedure with output parameter declaration
CREATE OR REPLACE PROCEDURE proc_with_single_output_parameters(param1 OUT NUMBER)
IS
BEGIN
param1 := 123;
END;
-- Procedure with output parameter being called
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_single_output_parameters
IS
var1 NUMBER;
BEGIN
proc_with_single_output_parameters(var1);
INSERT INTO TABLE01 VALUES(var1, -1);
END;
Exécution de scripts Snowflake¶
-- Procedure with output parameter declaration
CREATE OR REPLACE PROCEDURE proc_with_single_output_parameters (param1 OUT 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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := 123;
END;
$$;
-- Procedure with output parameter being called
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "TABLE01" **
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_single_output_parameters ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
var1 NUMBER(38, 18);
BEGIN
CALL
proc_with_single_output_parameters(:var1);
INSERT INTO TABLE01
VALUES(:var1, -1);
END;
$$;
Plusieurs paramètres Out¶
Oracle¶
-- Procedure with output parameters declaration
CREATE OR REPLACE PROCEDURE proc_with_multiple_output_parameters(
param1 OUT NUMBER,
param2 IN OUT NUMBER
)
IS
BEGIN
param1 := 123;
param2 := 456;
END;
-- Procedure with output parameters being called
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_multiple_output_parameters
IS
var1 NUMBER;
var2 NUMBER;
BEGIN
proc_with_multiple_output_parameters(var1, var2);
INSERT INTO TABLE01 VALUES(var1, var2);
END;
Exécution de scripts Snowflake¶
-- Procedure with output parameters declaration
CREATE OR REPLACE PROCEDURE proc_with_multiple_output_parameters (param1 OUT NUMBER(38, 18), param2 OUT 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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := 123;
param2 := 456;
END;
$$;
-- Procedure with output parameters being called
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "TABLE01" **
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_multiple_output_parameters ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
var1 NUMBER(38, 18);
var2 NUMBER(38, 18);
BEGIN
CALL
proc_with_multiple_output_parameters(:var1, :var2);
INSERT INTO TABLE01
VALUES(:var1, :var2);
END;
$$;
Afin de vérifier que la fonctionnalité est correctement émulée, la requête suivante va exécuter la procédure et un SELECT à partir de la table mentionnée précédemment.
Oracle¶
CALL proc_with_single_output_parameters();
CALL proc_with_multiple_output_parameters();
SELECT * FROM table01;
Résultat¶
COL1 |
COL2 |
|---|---|
123 |
-1 |
123 |
456 |
Exécution de scripts Snowflake¶
CALL proc_with_single_output_parameters();
CALL proc_with_multiple_output_parameters();
SELECT * FROM table01;
Résultat¶
COL1 |
COL2 |
|---|---|
123.000000000000000000 |
-1 |
123.000000000000000000 |
456.000000000000000000 |
Paramètres OUT du type de données de client¶
Lorsque le paramètre de sortie est un type client, le processus est similaire à un type de données classique.
Oracle¶
CREATE OR REPLACE PROCEDURE procedure_udtype_out_params (
p_employee_id NUMBER,
p_address OUT address_type
)
AS
BEGIN
-- Retrieve the employee's address based on the employee ID.
SELECT home_address INTO p_address
FROM employees
WHERE employee_id = p_employee_id;
END;
Exécution de scripts Snowflake¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "address_type", "employees" **
CREATE OR REPLACE PROCEDURE procedure_udtype_out_params (p_employee_id NUMBER(38, 18), p_address OUT VARIANT /*** SSC-FDM-0015 - REFERENCED CUSTOM TYPE 'address_type' IN QUERY NOT FOUND, USAGES MAY BE AFFECTED ***/
)
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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
-- Retrieve the employee's address based on the employee ID.
SELECT home_address INTO
:p_address
FROM
employees
WHERE employee_id = :p_employee_id;
END;
$$;
Paramètres OUT du curseur¶
Les paramètres de sortie du curseur ne sont pas pris en charge dans Snowflake. Malgré cela, une solution qui émule le comportement de Oracle est appliquée au code transformé. La procédure avec les paramètres de sortie génère une table temporaire avec un nom dynamique, et l’appel de procédure définira le nom de la table temporaire sous la forme d’une chaîne pour créer la table dans l’appel de la procédure.
Oracle¶
CREATE OR REPLACE PROCEDURE get_employees_by_dept (
p_department_id IN NUMBER,
p_employee_cursor OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_employee_cursor FOR
SELECT employee_id, first_name, last_name
FROM employees_sample
WHERE department_id = p_department_id
ORDER BY last_name;
END get_employees_by_dept;
/
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_cursor()
AS
DECLARE
l_emp_id NUMBER;
l_first_name VARCHAR;
l_last_name VARCHAR;
l_cursor SYS_REFCURSOR;
BEGIN
get_employees_by_dept(10, l_cursor);
LOOP
FETCH l_cursor INTO l_emp_id, l_first_name, l_last_name;
EXIT WHEN l_cursor%NOTFOUND;
INSERT INTO employee VALUES (l_emp_id, l_first_name, l_last_name);
END LOOP;
CLOSE l_cursor;
END;
/
Exécution de scripts Snowflake¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "employees_sample" **
CREATE OR REPLACE PROCEDURE get_employees_by_dept (p_department_id NUMBER(38, 18), p_employee_cursor VARCHAR
)
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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:p_employee_cursor) AS
SELECT employee_id, first_name, last_name
FROM
employees_sample
WHERE department_id = :p_department_id
ORDER BY last_name;
END;
$$;
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "employee" **
CREATE OR REPLACE PROCEDURE proc_calling_proc_with_cursor ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
l_emp_id NUMBER(38, 18);
l_first_name VARCHAR;
l_last_name VARCHAR;
l_cursor_res RESULTSET;
BEGIN
CALL
get_employees_by_dept(10, 'proc_calling_proc_with_cursor_l_cursor');
LET l_cursor CURSOR
FOR
SELECT
*
FROM
IDENTIFIER('proc_calling_proc_with_cursor_l_cursor');
OPEN l_cursor;
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH l_cursor INTO
:l_emp_id,
:l_first_name,
:l_last_name;
IF (l_emp_id IS NULL) THEN
EXIT;
END IF;
INSERT INTO employee
SELECT
:l_emp_id,
:l_first_name,
:l_last_name;
END LOOP;
CLOSE l_cursor;
END;
$$;
Paramètres OUT d’enregistrement¶
Les enregistrements ne sont pas pris en charge nativement dans Snowflake ; cependant, une solution de contournement a été utilisée pour les émuler en tant que paramètres de sortie. En définissant une variable OBJECT au lieu de l’enregistrement, nous pouvons émuler la structure des champs de l’enregistrement en affectant le résultat du paramètre de sortie à chaque propriété d’objet. En outre, pour chaque champ d’enregistrement affecté en tant que paramètre de sortie, une nouvelle variable avec le type de champ sera générée.
Oracle¶
CREATE OR REPLACE PROCEDURE procedure_with_out_params(
param1 OUT INTEGER,
param2 OUT INTEGER)
IS
BEGIN
param1 := 123;
param2 := 456;
END;
CREATE OR REPLACE PROCEDURE test_proc
IS
TYPE custom_record1 IS RECORD(field3 INTEGER, field4 INTEGER);
TYPE custom_record2 IS RECORD(field1 INTEGER, field2 custom_record1);
var1 custom_record2;
BEGIN
procedure_with_out_params(var1.field1, var1.field2.field4);
END;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE procedure_with_out_params (param1 OUT INTEGER, param2 OUT INTEGER)
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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := 123;
param2 := 456;
END;
$$;
CREATE OR REPLACE PROCEDURE test_proc ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
!!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
TYPE custom_record1 IS RECORD(field3 INTEGER, field4 INTEGER);
!!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
TYPE custom_record2 IS RECORD(field1 INTEGER, field2 custom_record1);
var1 OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - custom_record2 DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
var1_field1 INTEGER;
var1_field2_field4 INTEGER;
BEGIN
CALL
procedure_with_out_params(:var1_field1, :var1_field2_field4);
var1 := OBJECT_INSERT(COALESCE(var1, OBJECT_CONSTRUCT()), 'field1', :var1_field1, true);
var1 := OBJECT_INSERT(COALESCE(var1, OBJECT_CONSTRUCT()), 'field2', OBJECT_INSERT(COALESCE(var1:field2, OBJECT_CONSTRUCT()), 'field4', :var1_field2_field4, true), true);
END;
$$;
Variables de paquet comme paramètres OUT¶
Les paquets ne sont pas pris en charge dans Snowflake, donc leurs membres locaux, comme les variables ou les constantes, doivent également être préservés à l’aide d’une solution de contournement. Dans ce scénario, la variable de paquet est émulée à l’aide d’une variable de session qui est mise à jour après la définition d’une variable locale avec le résultat du paramètre de sortie.
Oracle¶
CREATE OR REPLACE PACKAGE scha1.pkg1 AS
PKG_VAR1 NUMBER;
END my_package;
/
CREATE OR REPLACE PROCEDURE PROC_WITH_OUT_PARAM(param1 OUT NUMBER)
AS
BEGIN
param1 := 0;
END;
CREATE OR REPLACE PROCEDURE PROC ()
AS
BEGIN
PROC_WITH_OUT_PARAM(param1 => scha1.pkg1.PKG_VAR1);
END;
Exécution de scripts Snowflake¶
CREATE SCHEMA IF NOT EXISTS SCHA1_PKG1
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/16/2025", "domain": "no-domain-provided" }}'
;
SET "SCHA1_PKG1.PKG_VAR1" = '~';
CREATE OR REPLACE PROCEDURE PROC_WITH_OUT_PARAM (param1 OUT 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" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := 0;
END;
$$;
CREATE OR REPLACE PROCEDURE PROC ()
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" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SCHA1_PKG1_PKG_VAR1 VARIANT;
BEGIN
CALL
PROC_WITH_OUT_PARAM(param1 => :SCHA1_PKG1_PKG_VAR1);
CALL UPDATE_PACKAGE_VARIABLE_STATE_UDF('SCHA1_PKG1.PKG_VAR1', TO_VARCHAR(:SCHA1_PKG1_PKG_VAR1));
END;
$$;
Problèmes connus¶
1. Procedures with output parameters inside packages may not work correctly¶
Actuellement, il y a un problème de collecte des informations sémantiques des procédures qui résident à l’intérieur des paquets, ce qui explique pourquoi la transformation des paramètres de sortie peut fonctionner partiellement ou ne pas fonctionner du tout. Cette question fait déjà l’objet d’un document de travail.
2. Some data types may not work properly¶
Comme le montre la transformation, lorsqu’on récupère la valeur à partir des procédures appelées, une conversion implicite est effectuée de VARIANT vers le type spécifié par la variable. Comme il existe de nombreux types de données possibles, certaines transformations peuvent échouer ou contenir des données différentes.
EWIs connexes¶
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-FDM-0007: Élément avec des dépendances manquantes.
SSC-FDM-0015: Type de données non reconnu.
NESTED PROCEDURES¶
Description¶
Dans PL/SQL d’Oracle, la définition NESTED PROCEDURES fait référence à une procédure déclarée et définie dans la section déclarative d’un autre bloc PL/SQL. Ce bloc parent peut être une autre procédure, une fonction ou un corps de paquet. Pour plus d’informations, reportez-vous à Déclarations et définitions des procédures Oracle.
Note
Les transformations décrites ci-dessous sont spécifiques aux procédures intégrées dans d’autres procédures ou paquets.
Modèles d’échantillons de sources¶
Mode de paramètre IN pour les procédures imbriquées¶
Le mot clé IN sera supprimé, car les procédures imbriquées de Snowflake ne prennent en charge que les paramètres IN implicitement.
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_basic_salary (
p_base_salary IN NUMBER,
p_bonus_amount IN NUMBER
)
AS
v_total_salary NUMBER := p_base_salary;
PROCEDURE add_bonus (
p_bonus_to_add IN NUMBER
)
AS
BEGIN
v_total_salary := v_total_salary + p_bonus_to_add;
INSERT INTO salary_logs (description, result_value)
VALUES ('Bonus added', v_total_salary);
END add_bonus;
BEGIN
INSERT INTO salary_logs (description, result_value)
VALUES ('Starting calculation', v_total_salary);
add_bonus(p_bonus_to_add => p_bonus_amount);
INSERT INTO salary_logs (description, result_value)
VALUES ('Final salary', v_total_salary);
END calculate_basic_salary;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_basic_salary (p_base_salary NUMBER(38, 18), p_bonus_amount 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
v_total_salary NUMBER(38, 18) := :p_base_salary;
add_bonus PROCEDURE (p_bonus_to_add NUMBER(38, 18)
)
RETURNS VARCHAR
AS
BEGIN
v_total_salary := :v_total_salary + :p_bonus_to_add;
INSERT INTO salary_logs(description, result_value)
VALUES ('Bonus added', :v_total_salary);
END;
BEGIN
INSERT INTO salary_logs(description, result_value)
VALUES ('Starting calculation', :v_total_salary);
CALL
add_bonus(:p_bonus_amount);
INSERT INTO salary_logs(description, result_value)
VALUES ('Final salary', :v_total_salary);
END;
$$;
Mode de paramètre OUT pour les procédures imbriquées¶
Les procédures imbriquées de SnowScript ne prennent pas en charge les paramètres de sortie. Pour répliquer cette fonctionnalité dans Snowflake, un type RETURN doit être créé en fonction des paramètres de sortie.
S’il n’y a qu’un seul paramètre de sortie, ce paramètre sera renvoyé à la fin. Dans les cas avec plusieurs paramètres de sortie, une construction d’objet sera générée contenant leurs valeurs. Pendant l’appel, ces valeurs seront affectées à une variable et, par la suite, ces résultats seront affectés aux variables ou paramètres correspondants.
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_net_salary (
p_base_salary IN NUMBER,
p_bonus_amount IN NUMBER,
p_net_salary OUT NUMBER
)
AS
PROCEDURE calculate_tax (
p_gross_amount IN NUMBER,
p_net_result OUT NUMBER
)
AS
BEGIN
p_net_result := p_gross_amount * 0.8;
END calculate_tax;
BEGIN
calculate_tax(p_base_salary + p_bonus_amount, p_net_salary);
END calculate_net_salary;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_net_salary (p_base_salary NUMBER(38, 18), p_bonus_amount NUMBER(38, 18), p_net_salary OUT 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
calculate_tax PROCEDURE (p_gross_amount NUMBER(38, 18), p_net_result NUMBER(38, 18)
)
RETURNS NUMBER
AS
BEGIN
p_net_result := :p_gross_amount * 0.8;
RETURN p_net_result;
END;
call_results NUMBER;
BEGIN
call_results := (
CALL
calculate_tax(:p_base_salary + :p_bonus_amount, :p_net_salary)
);
p_net_salary := :call_results;
END;
$$;
Plusieurs paramètres OUT dans les procédures imbriquées¶
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_comprehensive_salary (
p_base_salary IN NUMBER,
p_bonus_amount IN NUMBER,
p_final_salary OUT NUMBER,
p_tax_calculated OUT NUMBER,
p_total_gross OUT NUMBER
)
AS
l_running_total NUMBER := p_base_salary;
l_tax_amount NUMBER;
l_net_amount NUMBER;
PROCEDURE calculate_all_components (
p_base_amount IN NUMBER,
p_bonus_amt IN NUMBER,
p_running_total_inout IN OUT NUMBER,
p_tax_out OUT NUMBER,
p_net_out OUT NUMBER
)
AS
BEGIN
p_running_total_inout := p_base_amount + p_bonus_amt;
p_tax_out := p_running_total_inout * 0.25;
p_net_out := p_running_total_inout - p_tax_out;
END calculate_all_components;
BEGIN
calculate_all_components(
p_base_amount => p_base_salary,
p_bonus_amt => p_bonus_amount,
p_running_total_inout => l_running_total,
p_tax_out => l_tax_amount,
p_net_out => l_net_amount
);
p_final_salary := l_net_amount;
p_tax_calculated := l_tax_amount;
p_total_gross := l_running_total;
END calculate_comprehensive_salary;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_comprehensive_salary (p_base_salary NUMBER(38, 18), p_bonus_amount NUMBER(38, 18), p_final_salary OUT NUMBER(38, 18), p_tax_calculated OUT NUMBER(38, 18), p_total_gross OUT 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
l_running_total NUMBER(38, 18) := :p_base_salary;
l_tax_amount NUMBER(38, 18);
l_net_amount NUMBER(38, 18);
calculate_all_components PROCEDURE (p_base_amount NUMBER(38, 18), p_bonus_amt NUMBER(38, 18), p_running_total_inout NUMBER(38, 18), p_tax_out NUMBER(38, 18), p_net_out NUMBER(38, 18)
)
RETURNS VARIANT
AS
BEGIN
p_running_total_inout := :p_base_amount + :p_bonus_amt;
p_tax_out := :p_running_total_inout * 0.25;
p_net_out := :p_running_total_inout - :p_tax_out;
RETURN OBJECT_CONSTRUCT('p_running_total_inout', :p_running_total_inout, 'p_tax_out', :p_tax_out, 'p_net_out', :p_net_out);
END;
call_results VARIANT;
BEGIN
call_results := (
CALL
calculate_all_components(:p_base_salary, :p_bonus_amount, :l_running_total, :l_tax_amount, :l_net_amount)
);
l_running_total := :call_results:p_running_total_inout;
l_tax_amount := :call_results:p_tax_out;
l_net_amount := :call_results:p_net_out;
p_final_salary := :l_net_amount;
p_tax_calculated := :l_tax_amount;
p_total_gross := :l_running_total;
END;
$$;
Procédures imbriquées à plusieurs niveaux¶
Snowflake n’autorise qu’un seul niveau d’imbrication pour les procédures imbriquées. Par conséquent, une procédure imbriquée dans une autre procédure imbriquée n’est pas prise en charge. Si cela se produit, la transformation inclura l’erreur !!!RESOLVE EWI!!! /*** SSC-EWI-0111 - ONLY ONE LEVEL OF NESTING IS ALLOWED FOR NESTED PROCEDURES IN SNOWFLAKE. ***/!!!
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_executive_salary (
p_result OUT NUMBER
)
AS
PROCEDURE calculate_senior_level (
senior_result OUT NUMBER
)
AS
PROCEDURE calculate_base_level (
base_result OUT NUMBER
)
AS
BEGIN
base_result := 75000;
END calculate_base_level;
BEGIN
calculate_base_level(senior_result);
senior_result := senior_result * 1.5;
END calculate_senior_level;
BEGIN
calculate_senior_level(p_result);
END calculate_executive_salary;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_executive_salary (p_result OUT 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
calculate_senior_level PROCEDURE (senior_result NUMBER(38, 18)
)
RETURNS NUMBER
AS
DECLARE
!!!RESOLVE EWI!!! /*** SSC-EWI-0111 - ONLY ONE LEVEL OF NESTING IS ALLOWED FOR NESTED PROCEDURES IN SNOWFLAKE. ***/!!!
PROCEDURE calculate_base_level (
base_result OUT NUMBER
)
AS
BEGIN
base_result := 75000;
END calculate_base_level;
call_results NUMBER;
BEGIN
call_results := (
CALL
calculate_base_level(:senior_result)
);
senior_result := :call_results;
senior_result := :senior_result * 1.5;
RETURN senior_result;
END;
call_results NUMBER;
BEGIN
call_results := (
CALL
calculate_senior_level(:p_result)
);
p_result := :call_results;
END;
$$;
Valeurs par défaut dans les procédures imbriquées¶
Les arguments de procédures imbriquées ne prennent pas en charge les clauses par défaut. Par conséquent, si un appel de procédure imbriqué omet un paramètre facultatif, la valeur par défaut de cet argument doit être soumise dans l’appel de procédure. SnowConvert AI identifie automatiquement ces scénarios et remplit les appels de procédure de manière appropriée.
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_total_compensation (
p_base_salary IN NUMBER,
p_final_compensation OUT NUMBER
)
AS
v_total NUMBER := p_base_salary;
l_bonus NUMBER;
PROCEDURE add_bonus (
p_salary_amount IN NUMBER,
p_multiplier IN NUMBER DEFAULT 1.1,
p_calculated_bonus OUT NUMBER
)
AS
BEGIN
p_calculated_bonus := p_salary_amount * (p_multiplier - 1);
END add_bonus;
BEGIN
add_bonus(p_base_salary, p_calculated_bonus => l_bonus);
v_total := v_total + l_bonus;
add_bonus(p_base_salary, 1.2, p_calculated_bonus => l_bonus);
v_total := v_total + l_bonus;
p_final_compensation := v_total;
END calculate_total_compensation;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_total_compensation (p_base_salary NUMBER(38, 18), p_final_compensation OUT 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
v_total NUMBER(38, 18) := :p_base_salary;
l_bonus NUMBER(38, 18);
add_bonus PROCEDURE (p_salary_amount NUMBER(38, 18), p_multiplier NUMBER(38, 18), p_calculated_bonus NUMBER(38, 18)
)
RETURNS NUMBER
AS
BEGIN
p_calculated_bonus := :p_salary_amount * (:p_multiplier - 1);
RETURN p_calculated_bonus;
END;
call_results NUMBER;
BEGIN
call_results := (
CALL
add_bonus(:p_base_salary, 1.1, :l_bonus)
);
l_bonus := :call_results;
v_total := :v_total + :l_bonus;
call_results := (
CALL
add_bonus(:p_base_salary, 1.2, :l_bonus)
);
l_bonus := :call_results;
v_total := :v_total + :l_bonus;
p_final_compensation := :v_total;
END;
$$;
Surcharge de procédures imbriquées¶
Snowflake ne prend pas en charge la surcharge des procédures imbriquées. Si cela se produit, l’EWI SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED sera ajouté.
Oracle¶
CREATE OR REPLACE PROCEDURE demonstrate_salary_calculations(
final_summary OUT VARCHAR2
)
AS
result1 VARCHAR2(100);
result2 VARCHAR2(100);
result3 VARCHAR2(100);
PROCEDURE calculate_salary(
output OUT VARCHAR2
)
AS
BEGIN
output := 'Standard: 55000';
END;
PROCEDURE calculate_salary(
base_amount IN NUMBER,
output OUT VARCHAR2
)
AS
BEGIN
output := 'Calculated: ' || (base_amount * 1.15);
END;
PROCEDURE calculate_salary(
employee_level IN VARCHAR2,
output OUT VARCHAR2
)
AS
BEGIN
output := 'Level ' || UPPER(employee_level) || ': 60000';
END;
BEGIN
calculate_salary(result1);
calculate_salary(50000, result2);
calculate_salary('senior', result3);
final_summary := result1 || ' | ' || result2 || ' | ' || result3;
END demonstrate_salary_calculations;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE demonstrate_salary_calculations (final_summary OUT VARCHAR
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
result1 VARCHAR(100);
result2 VARCHAR(100);
result3 VARCHAR(100);
calculate_salary PROCEDURE(output VARCHAR
)
RETURNS VARCHAR
AS
BEGIN
output := 'Standard: 55000';
RETURN output;
END;
!!!RESOLVE EWI!!! /*** SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED. ***/!!!
calculate_salary PROCEDURE(base_amount NUMBER(38, 18), output VARCHAR
)
RETURNS VARCHAR
AS
BEGIN
output := 'Calculated: ' || NVL((:base_amount * 1.15) :: STRING, '');
RETURN output;
END;
!!!RESOLVE EWI!!! /*** SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED. ***/!!!
calculate_salary PROCEDURE(employee_level VARCHAR, output VARCHAR
)
RETURNS VARCHAR
AS
BEGIN
output := 'Level ' || NVL(UPPER(:employee_level) :: STRING, '') || ': 60000';
RETURN output;
END;
call_results VARCHAR;
BEGIN
call_results := (
CALL
calculate_salary(:result1)
);
result1 := :call_results;
call_results := (
CALL
calculate_salary(50000, :result2)
);
result2 := :call_results;
call_results := (
CALL
calculate_salary('senior', :result3)
);
result3 := :call_results;
final_summary := NVL(:result1 :: STRING, '') || ' | ' || NVL(:result2 :: STRING, '') || ' | ' || NVL(:result3 :: STRING, '');
END;
$$;
Procédure imbriquée sans liste de paramètres¶
Dans Snowflake, une définition de procédure imbriquée nécessite des parenthèses vides () pour être syntaxiquement valide lorsqu’il n’a pas de paramètres ; contrairement à Oracle, où ils ne sont pas nécessaires. SnowConvert AI les ajoutera automatiquement au cours de la traduction.
Oracle¶
CREATE OR REPLACE PROCEDURE reset_salary_system
AS
PROCEDURE cleanup_salary_data
AS
BEGIN
DELETE FROM salary_results;
INSERT INTO salary_results VALUES (0);
END cleanup_salary_data;
BEGIN
cleanup_salary_data();
END reset_salary_system;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE reset_salary_system ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "07/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
cleanup_salary_data PROCEDURE ()
RETURNS VARCHAR
AS
BEGIN
DELETE FROM
salary_results;
INSERT INTO salary_results
VALUES (0);
END;
BEGIN
CALL
cleanup_salary_data();
END;
$$;
Procédure imbriquée avec paramètre de sortie REFCURSOR¶
Oracle¶
CREATE OR REPLACE PROCEDURE process_department_salaries (
p_department_id IN NUMBER
)
AS
v_employee_cursor SYS_REFCURSOR;
v_employee_id employees.employee_id%TYPE;
v_first_name employees.first_name%TYPE;
v_last_name employees.last_name%TYPE;
PROCEDURE get_department_employees (
p_dept_id IN NUMBER,
p_cursor OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_cursor FOR
SELECT employee_id, first_name, last_name
FROM employees
WHERE department_id = p_dept_id;
END get_department_employees;
BEGIN
get_department_employees(p_department_id, v_employee_cursor);
LOOP
FETCH v_employee_cursor INTO v_employee_id, v_first_name, v_last_name;
EXIT WHEN v_employee_cursor%NOTFOUND;
INSERT INTO salary_audit VALUES (v_employee_id, v_first_name || ' ' || v_last_name);
END LOOP;
CLOSE v_employee_cursor;
END process_department_salaries;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE process_department_salaries (p_department_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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
v_employee_cursor_res RESULTSET;
v_employee_id NUMBER(38, 18);
v_first_name VARCHAR(50);
v_last_name VARCHAR(50);
get_department_employees PROCEDURE (p_dept_id NUMBER(38, 18), p_cursor VARCHAR
)
RETURNS VARCHAR
AS
BEGIN
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:p_cursor) AS
SELECT employee_id, first_name, last_name
FROM
employees
WHERE department_id = :p_dept_id;
RETURN p_cursor;
END;
call_results VARCHAR;
BEGIN
call_results := (
CALL
get_department_employees(:p_department_id, 'process_department_salaries_v_employee_cursor')
);
LET v_employee_cursor CURSOR
FOR
SELECT
*
FROM
IDENTIFIER('process_department_salaries_v_employee_cursor');
OPEN v_employee_cursor;
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH v_employee_cursor INTO
:v_employee_id,
:v_first_name,
:v_last_name;
IF (v_employee_id IS NULL) THEN
EXIT;
END IF;
INSERT INTO salary_audit
SELECT
:v_employee_id,
NVL(:v_first_name :: STRING, '') || ' ' || NVL(:v_last_name :: STRING, '');
END LOOP;
CLOSE v_employee_cursor;
END;
$$;
Procédure imbriquée avec option de paramètre NOCOPY¶
Dans PL/SQL d’Oracle, le mot-clé NOCOPY est un indice d’optimisation pour les paramètres de procédure OUT et IN OUT. Par défaut, Oracle transmet ces paramètres par valeur, ce qui crée une copie coûteuse des données pendant l’appel, qui sont copiées à la fin. Cela peut entraîner une surcharge importante des performances pour les grandes structures de données.
NOCOPY demande à Oracle de transmettre les paramètres par référence, ce qui permet à la procédure de modifier directement les données d’origine. Cela élimine la surcharge générée par la copie et améliore les performances. Cependant, les modifications sont immédiates et ne sont pas implicitement annulées si une exception non gérée se produit dans la procédure.
Par conséquent, nous supprimerons l’option de paramètres NOCOPY et ajouterons FDM SSC-FDM-OR0050 - EXCEPTIONS WITH NOCOPY PARAMETERS MAY LEAD TO DATA INCONSISTENCY. En effet, l’exécution de la procédure s’arrête en cas d’exception, ce qui empêche l’instruction RETURN d’être atteinte. En conséquence, la variable du bloc de déclaration de l’appelant conserve ses valeurs initiales, car la procédure ne parvient pas à renvoyer avec succès une nouvelle valeur pour l’affectation.
Oracle¶
CREATE OR REPLACE PROCEDURE calculate_bonus_with_nocopy (
p_base_salary IN NUMBER,
p_multiplier IN NUMBER,
p_bonus_result OUT NOCOPY NUMBER
)
AS
PROCEDURE compute_bonus(bonus_amount OUT NOCOPY NUMBER)
AS
BEGIN
IF p_multiplier = 0 THEN
bonus_amount := NULL;
ELSE
bonus_amount := p_base_salary * p_multiplier * 0.1;
END IF;
END compute_bonus;
BEGIN
compute_bonus(p_bonus_result);
END calculate_bonus_with_nocopy;
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE calculate_bonus_with_nocopy (p_base_salary NUMBER(38, 18), p_multiplier NUMBER(38, 18), p_bonus_result OUT 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/22/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
compute_bonus PROCEDURE(bonus_amount
--** SSC-FDM-OR0050 - EXCEPTIONS WITH NOCOPY PARAMETERS MAY LEAD TO DATA INCONSISTENCY. **
NUMBER(38, 18))
RETURNS NUMBER
AS
BEGIN
IF (:p_multiplier = 0) THEN
bonus_amount := NULL;
ELSE
bonus_amount := :p_base_salary * :p_multiplier * 0.1;
END IF;
RETURN bonus_amount;
END;
call_results NUMBER;
BEGIN
call_results := (
CALL
compute_bonus(:p_bonus_result)
);
p_bonus_result := :call_results;
END;
$$;
Problèmes connus¶
1. Multi-level Nested Procedures¶
Les efforts de transformation pour les procédures imbriquées dans Snowflake sont limités à celles imbriquées directement dans d’autres procédures, ne prenant en charge qu’un seul niveau d’imbrication. Si le niveau d’imbrication dépasse un, ou si une procédure est imbriquée dans une fonction autonome, la transformation n’est pas prise en charge, et l’EWI **RESOLVE EWI** /**** SSC-EWI-0111 - ONLY ONE LEVEL OF NESTING IS ALLOWED FOR NESTED PROCEDURES IN SNOWFLAKE. ****/! sera ajouté.
2. Nested procedures overloading¶
De plus, la surcharge des procédures imbriquées n’est pas prise en charge dans Snowflake. Dans de tels cas, l’EWI **RESOLVE EWI** /**** SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED. ****/! sera ajouté.
3. Nested procedures within anonymous blocks¶
La transformation pour les procédures imbriquées dans les blocs anonymes est actuellement en attente. L’EWI **RESOLVE EWI** /**** SSC-EWI-OR0057 - TRANSFORMATION FOR NESTED PROCEDURE OR FUNCTION IS NOT SUPPORTED IN THIS SCENARIO ****/! sera ajouté.
EWIs connexes¶
SSC-FDM-OR0050: Les exceptions avec les paramètres
NOCOPYpeuvent entraîner une incohérence des données.SSC-EWI-OR0057: La transformation pour la procédure ou la fonction imbriquée n’est pas prise en charge.
SSC-EWI-0111: Un seul niveau d’imbrication est autorisé pour les procédures imbriquées dans Snowflake.
SSC-EWI-0112: La surcharge des procédures imbriquées n’est pas prise en charge.
PROCEDURE CALL¶
Référence de traduction pour PROCEDURE CALL alias SUBPROGRAM INVOCATION
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
Cette section décrit la syntaxe des invocations de sous-programmes à l’intérieur des blocs PL, tels que les procédures ou les blocs anonymes.
Pour plus d’informations à ce sujet, veuillez vous référer à la documentation Oracle sur les sous-programmes : (Référence linguistique Oracle PL/SQL Instruction d’invocation de sous-programme)
Les appels de procédure peuvent être migrés vers Snowflake tant qu’il n’y a pas de paramètres optionnels et que leur ordre correspond aux paramètres formels. Veuillez noter que les invocations de procédures sont transférées vers une instruction Call.
Syntaxe d’appel du sous- programme Oracle¶
<subprogram invocation> := subprogram_name [ ( [ parameter [, parameter]... ] ) ]
<parameter> := {
<actual parameter>
| <formal parameter name> => <actual parameter>
}
Snowflake Scripting prend en charge cette instruction, avec toutefois quelques différences fonctionnelles.
Syntaxe d’appel du sous- programme Snowflake Scripting¶
<subprogram invocation> := CALL subprogram_name [ ( [ parameter [, parameter]... ] ) ]
<parameter> := {
<actual parameter>
| <formal parameter name> => <actual parameter>
}
Modèles d’échantillons de sources¶
Note
Examinez la table et la procédure suivantes pour les exemples ci-dessous.
Oracle¶
CREATE TABLE procedure_call_test_table(
col1 INTEGER
);
-- Simple Called procedure
CREATE OR REPLACE PROCEDURE called_procedure (param1 INTEGER)
AS
BEGIN
INSERT INTO procedure_call_test_table VALUES (param1);
END;
Snowflake¶
CREATE OR REPLACE TABLE procedure_call_test_table (
col1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;
-- Simple Called procedure
CREATE OR REPLACE PROCEDURE called_procedure (param1 INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO procedure_call_test_table
VALUES (:param1);
END;
$$;
Appel simple¶
Oracle¶
CREATE OR REPLACE PROCEDURE simple_calling_procedure
AS
BEGIN
called_procedure(1);
END;
CALL simple_calling_procedure();
SELECT * FROM procedure_call_test_table;
Résultat¶
COL1 |
|---|
1 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE simple_calling_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CALL
called_procedure(1);
END;
$$;
CALL simple_calling_procedure();
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "procedure_call_test_table" **
SELECT * FROM
procedure_call_test_table;
Résultat¶
COL1 |
|---|
1 |
Appel d’une procédure avec un paramètre facultatif¶
Avertissement
Cet exemple contient une intervention manuelle pour certaines différences fonctionnelles et est utilisé pour les expliquer. Pour plus d’informations sur ces différences, veuillez consulter la section Problèmes connus ci-dessous.
Oracle¶
-- Procedure with optional parameters
CREATE OR REPLACE PROCEDURE proc_optional_parameters (param1 INTEGER, param2 INTEGER := 8, param3 INTEGER)
AS
BEGIN
INSERT INTO procedure_call_test_table VALUES (param1);
INSERT INTO procedure_call_test_table VALUES (param2);
INSERT INTO procedure_call_test_table VALUES (param3);
END;
CREATE OR REPLACE PROCEDURE calling_procedure
AS
BEGIN
-- positional convention
proc_optional_parameters(1, 2, 3);
-- named convention
proc_optional_parameters(param1 => 4, param2 => 5, param3 => 6);
-- named convention, second gets ommited
proc_optional_parameters(param1 => 7, param3 => 9);
-- named convention, different order
proc_optional_parameters(param3 => 12, param1 => 10, param2 => 11);
END;
CALL calling_procedure();
SELECT * FROM procedure_call_test_table;
Résultat¶
COL1 |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Exécution de scripts Snowflake¶
-- Procedure with optional parameters
CREATE OR REPLACE PROCEDURE proc_optional_parameters
!!!RESOLVE EWI!!! /*** SSC-EWI-0002 - DEFAULT PARAMETERS MAY NEED TO BE REORDERED. SNOWFLAKE ONLY SUPPORTS DEFAULT PARAMETERS AT THE END OF THE PARAMETERS DECLARATIONS ***/!!!
(param1 INTEGER, param2 INTEGER DEFAULT 8, param3 INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO procedure_call_test_table
VALUES (:param1);
INSERT INTO procedure_call_test_table
VALUES (:param2);
INSERT INTO procedure_call_test_table
VALUES (:param3);
END;
$$;
CREATE OR REPLACE PROCEDURE calling_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CALL
-- positional convention
proc_optional_parameters(1, 2, 3);
CALL
-- named convention
proc_optional_parameters(param1 => 4, param2 => 5, param3 => 6);
CALL
-- named convention, second gets ommited
proc_optional_parameters(param1 => 7, param3 => 9);
CALL
-- named convention, different order
proc_optional_parameters(param1 => 10, param2 => 11, param3 => 12);
END;
$$;
CALL calling_procedure();
SELECT * FROM
procedure_call_test_table;
Résultat¶
COL1 |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Problèmes connus¶
1. Calling Subprograms with default values is not supported¶
Snowflake ne prend pas en charge l’ensemble des valeurs par défaut des paramètres. Ceux-ci devront donc être renseignés à chaque appel.
2. Named parameters are accepted, but not functionally equivalent¶
Ces paramètres ne causeront pas d’erreurs de compilation lorsqu’ils seront exécutés dans Snowflake. cependant, les appels les placent toujours de manière positionnelle. C’est pourquoi l’ordre de ces paramètres doit être vérifié. SnowConvert AI ne prend pas en charge la vérification ni la réorganisation de ces paramètres.
3. Calling Subprograms with Out Parameters is not supported¶
Snowflake ne prend pas en charge les modes de paramètres, mais une solution est en cours d’implémentation pour émuler leur fonctionnalité. Pour obtenir plus d’informations sur la transformation des paramètres de sortie, veuillez consulter l’article suivant : Paramètres de sortie.
EWIs connexes¶
SSC-EWI-0002: Il peut être nécessaire de réorganiser les paramètres par défaut.
SSC-FDM-0007: Élément avec des dépendances manquantes.
RAISE¶
Description¶
L’instruction
RAISElève explicitement une exception.En dehors d’un gestionnaire d’exception, vous devez spécifier le nom de l’exception. À l’intérieur d’un gestionnaire d’exception, si vous omettez le nom de l’exception, l’instruction
RAISElève à nouveau l’exception en cours. (Référence linguistique PL/SQL Instruction Raise)
L’instruction est entièrement prise en charge par Snowflake Scripting, mais tenez compte du fait qu’il peut y avoir des différences entre l’instruction Commit et l’instruction Rollback.
RAISE <exception_name> ;
Snowflake Scripting prend en charge cette instruction.
RAISE <exception_name> ;
Modèles d’échantillons de sources¶
Levée d’exception simple¶
Oracle¶
CREATE OR REPLACE PROCEDURE simple_exception_throw_handle(param1 INTEGER)
IS
my_exception EXCEPTION;
my_other_exception EXCEPTION;
BEGIN
IF param1 > 0
THEN RAISE my_exception;
END IF;
EXCEPTION
WHEN my_exception THEN
IF param1 = 1
THEN RAISE;
END IF;
RAISE my_other_exception;
END;
--Completes without issue
CALL simple_exception_throw_handle(0);
--Throws my_exception
CALL simple_exception_throw_handle(1);
--Throws my_exception, catches then raises second my_other_exception
CALL simple_exception_throw_handle(2);
Résultat¶
Call completed.
-----------------------------------------------------------------------
Error starting at line : 31 in command -
CALL simple_exception_throw_handle(1)
Error report -
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYSTEM.SIMPLE_EXCEPTION_THROW_HANDLE", line 12
ORA-06512: at "SYSTEM.SIMPLE_EXCEPTION_THROW_HANDLE", line 7
ORA-06512: at line 1
06510. 00000 - "PL/SQL: unhandled user-defined exception"
*Cause: A user-defined exception was raised by PL/SQL code, but
not handled.
*Action: Fix the problem causing the exception or write an exception
handler for this condition. Or you may need to contact your
application administrator or DBA.
-----------------------------------------------------------------------
Error starting at line : 33 in command -
CALL simple_exception_throw_handle(2)
Error report -
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYSTEM.SIMPLE_EXCEPTION_THROW_HANDLE", line 14
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYSTEM.SIMPLE_EXCEPTION_THROW_HANDLE", line 7
ORA-06512: at line 1
06510. 00000 - "PL/SQL: unhandled user-defined exception"
*Cause: A user-defined exception was raised by PL/SQL code, but
not handled.
*Action: Fix the problem causing the exception or write an exception
handler for this condition. Or you may need to contact your
application administrator or DBA.
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE simple_exception_throw_handle (param1 INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
my_exception EXCEPTION;
my_other_exception EXCEPTION;
BEGIN
IF (:param1 > 0) THEN
RAISE my_exception;
END IF;
EXCEPTION
WHEN my_exception THEN
IF (:param1 = 1) THEN
RAISE;
END IF;
RAISE my_other_exception;
END;
$$;
--Completes without issue
CALL simple_exception_throw_handle(0);
--Throws my_exception
CALL simple_exception_throw_handle(1);
--Throws my_exception, catches then raises second my_other_exception
CALL simple_exception_throw_handle(2);
Résultat¶
Call Completed
-----------------------------------------------------------------------
Uncaught exception of type 'MY_EXCEPTION' on line 7 at position 9
-----------------------------------------------------------------------
Uncaught exception of type 'MY_OTHER_EXCEPTION' on line 14 at position 9
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
Pas d’EWIs connexes.
RAISE_APPICATION_ERROR¶
Référence de traduction pour l’instruction raise_application_error.
Description générale¶
La procédure RAISE_APPLICATION_ERROR vous permet d’émettre des messages d’erreur définis par l’utilisateur ORA- à partir de sous-programmes stockés. Ainsi, vous pouvez signaler les erreurs à votre application et éviter de renvoyer des exceptions non gérées (Documentation Oracle).
Syntaxe Oracle¶
raise_application_error(
error_number, message[, {TRUE | FALSE}]);
Note
error_number est un entier négatif compris entre -20000 .. -20999 et message est une chaîne de caractères d’une longueur maximale de 2048 octets.
Si le troisième paramètre facultatif est TRUE, l’erreur est placée sur la pile des erreurs précédentes. Si le paramètre est FALSE (valeur par défaut), l’erreur remplace toutes les erreurs précédentes.
L’instruction équivalente dans Snowflake est la clause RAISE. Néanmoins, il est exigé de déclarer l’exception définie par l’utilisateur en tant que variable avant d’appeler l’instruction RAISE pour celle-ci.
Syntaxe Snowflake¶
<exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
Note
Pour plus d’informations, consultez la documentation Snowflake.
Modèles d’échantillons de sources¶
1. Exception in functions without declaring section¶
Dans ce scénario, la fonction sans section de déclaration est traduite en procédure avec la déclaration d’exception. Veuillez noter que :
Le nom de la variable d’exception est déclaré en casse majuscule.
Le nom de la variable d’exception est basé sur la description et une terminaison est composée d’un nom de code d’exception suivi d’un numéro consécutif.
La section de déclaration est créée même si la fonction ou la procédure initiale ne la contient pas.
Oracle¶
CREATE OR REPLACE FUNCTION TEST(
SAMPLE_A IN NUMBER DEFAULT NULL,
SAMPLE_B IN NUMBER DEFAULT NULL
)
RETURN NUMBER
AS
BEGIN
raise_application_error(-20001, 'First exception message', FALSE);
raise_application_error(-20002, 'Second exception message');
RETURN 1;
END TEST;
Sortie¶
ORA-20001: First exception message
Snowflake¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE TEST (
SAMPLE_A NUMBER(38, 18) DEFAULT NULL,
SAMPLE_B NUMBER(38, 18) 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": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
FIRST_EXCEPTION_MESSAGE_EXCEPTION_CODE_0 EXCEPTION (-20001, 'FIRST EXCEPTION MESSAGE');
SECOND_EXCEPTION_MESSAGE_EXCEPTION_CODE_1 EXCEPTION (-20002, 'SECOND EXCEPTION MESSAGE');
BEGIN
--** SSC-FDM-OR0011 - ADD TO STACK OF ERRORS IS NOT SUPPORTED, BOOLEAN ARGUMENT FALSE WAS REMOVED. **
RAISE FIRST_EXCEPTION_MESSAGE_EXCEPTION_CODE_0;
RAISE SECOND_EXCEPTION_MESSAGE_EXCEPTION_CODE_1;
RETURN 1;
END;
$$;
Sortie¶
FIRST EXCEPTION MESSAGE
2. Exception code number outside limits¶
L’exemple suivant montre la traduction commentée dans le corps de la procédure. C’est parce que le code est en dehors des limites applicables à Snowflake. La solution consiste à remplacer le code d’exception par un code disponible dans la section des requêtes.
Oracle¶
CREATE OR REPLACE FUNCTION TEST(
SAMPLE_A IN NUMBER DEFAULT NULL,
SAMPLE_B IN NUMBER DEFAULT NULL
)
RETURN NUMBER
AS
BEGIN
raise_application_error(-20000, 'My exception message');
RETURN 1;
END TEST;
Sortie¶
ORA-20000: My exception message
Snowflake¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE TEST (
SAMPLE_A NUMBER(38, 18) DEFAULT NULL,
SAMPLE_B NUMBER(38, 18) 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": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
MY_EXCEPTION_MESSAGE_EXCEPTION_CODE_0 EXCEPTION (-20000, 'MY EXCEPTION MESSAGE');
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-OR0099 - EXCEPTION CODE NUMBER EXCEEDS SNOWFLAKE SCRIPTING LIMITS ***/!!!
RAISE MY_EXCEPTION_MESSAGE_EXCEPTION_CODE_0;
RETURN 1;
END;
$$;
Sortie¶
Invalid error code '-20,000'. Must be between -20,999 and -20,000
3. Exception stack functionality¶
La fonctionnalité de la pile d’exceptions n’est pas prise en charge dans Snowflake et est supprimée de la déclaration d’exception.
Oracle¶
CREATE OR REPLACE FUNCTION TEST(
SAMPLE_A IN NUMBER DEFAULT NULL,
SAMPLE_B IN NUMBER DEFAULT NULL
)
RETURN NUMBER
AS
BEGIN
raise_application_error(-20001, 'My exception message', TRUE);
RETURN 1;
END TEST;
Sortie¶
ORA-20001: My exception message
Snowflake¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE TEST (
SAMPLE_A NUMBER(38, 18) DEFAULT NULL,
SAMPLE_B NUMBER(38, 18) 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": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
MY_EXCEPTION_MESSAGE_EXCEPTION_CODE_0 EXCEPTION (-20001, 'MY EXCEPTION MESSAGE');
BEGIN
--** SSC-FDM-OR0011 - ADD TO STACK OF ERRORS IS NOT SUPPORTED, BOOLEAN ARGUMENT TRUE WAS REMOVED. **
RAISE MY_EXCEPTION_MESSAGE_EXCEPTION_CODE_0;
RETURN 1;
END;
$$;
Sortie¶
MY EXCEPTION MESSAGE
4. Multiple exceptions with the same exception code¶
Plusieurs exceptions identiques peuvent coexister dans la section de déclaration et dans les instructions raise.
Oracle¶
CREATE OR REPLACE FUNCTION TEST(
SAMPLE_A IN NUMBER DEFAULT NULL,
SAMPLE_B IN NUMBER DEFAULT NULL
)
RETURN NUMBER
AS
BEGIN
IF TRUE THEN
raise_application_error(-20001, 'The first exception');
ELSE
raise_application_error(-20001, 'Other exception inside');
END IF;
RETURN 1;
END TEST;
Sortie¶
ORA-20000: The first exception
Snowflake¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE TEST (
SAMPLE_A NUMBER(38, 18) DEFAULT NULL,
SAMPLE_B NUMBER(38, 18) 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": "07/14/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
THE_FIRST_EXCEPTION_EXCEPTION_CODE_0 EXCEPTION (-20001, 'THE FIRST EXCEPTION');
OTHER_EXCEPTION_INSIDE_EXCEPTION_CODE_1 EXCEPTION (-20001, 'OTHER EXCEPTION INSIDE');
BEGIN
IF (TRUE) THEN
RAISE THE_FIRST_EXCEPTION_EXCEPTION_CODE_0;
ELSE
RAISE OTHER_EXCEPTION_INSIDE_EXCEPTION_CODE_1;
END IF;
RETURN 1;
END;
$$;
Sortie¶
THE FIRST EXCEPTION
Problèmes connus¶
La fonction SQLREM peut être réexaminée.
Le numéro de code d’exception en dehors des limites applicables dans Snowflake doit être modifié en un code d’exception disponible.
L’ajout à une pile d’erreurs n’est pas pris en charge.
EWIs connexes¶
SSC-EWI-OR0099: Le code d’exception dépasse la limite de Snowflake Scripting.
SSC-FDM-0029: La fonction définie par l’utilisateur a été transformée en procédure Snowflake.
SSC-FDM-OR0011: L’argument booléen a été supprimé, car l’options « ajouter à la pile » n’est pas prise en charge.
UDF CALL¶
Référence de traduction pour la fonction définie par l’utilisateur (UDF) Call
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
Comme cela est largement reconnu, les fonctions définies par l’utilisateur non scalaires (UDFs) dans Oracle sont converties en procédures stockées Snowflake pour prendre en charge des fonctionnalités plus complexes.
Cette transformation modifie également la manière dont la fonction est invoquée, passant d’un appel de fonction traditionnel à un appel de procédure stockée.
Pour plus de détails concernant l’invocation des procédures stockées, référez-vous à la documentation accessible ici : PROCEDURE CALL.
Modèles d’échantillons de sources¶
Note
Considérez la fonction et les tables suivantes pour les exemples ci-dessous.
Oracle¶
CREATE OR REPLACE FUNCTION sum_to_varchar_function(p_number1 IN NUMBER, p_number2 IN NUMBER)
RETURN VARCHAR
IS
result VARCHAR(100);
BEGIN
result := TO_CHAR(p_number1 + p_number2);
RETURN result;
END sum_to_varchar_function;
CREATE TABLE example_table (
id NUMBER,
column1 NUMBER
);
INSERT INTO example_table VALUES (1, 15);
CREATE TABLE result_table (
id NUMBER,
result_col VARCHAR(100)
);
Snowflake¶
CREATE OR REPLACE FUNCTION sum_to_varchar_function (p_number1 NUMBER(38, 18), p_number2 NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "11/14/2024", "domain": "test" }}'
AS
$$
WITH declaration_variables_cte1 AS
(
SELECT
TO_CHAR(p_number1 + p_number2) AS
result
)
SELECT
result
FROM
declaration_variables_cte1
$$;
CREATE OR REPLACE TABLE example_table (
id NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
column1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "11/14/2024", "domain": "test" }}'
;
INSERT INTO example_table
VALUES (1, 15);
CREATE OR REPLACE TABLE result_table (
id NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
result_col VARCHAR(100)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "11/14/2024", "domain": "test" }}'
;
Appel d’UDF¶
Oracle¶
CREATE OR REPLACE PROCEDURE procedure_calling_function(param1 IN NUMBER)
IS
result_value VARCHAR(200);
BEGIN
result_value := sum_to_varchar_function(3, param1);
INSERT INTO result_table VALUES (1, result_value);
END;
BEGIN
procedure_calling_function(5);
END;
Résultat¶
ID RESULT_COL
1 8
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE procedure_calling_function (param1 NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
result_value VARCHAR(200);
BEGIN
result_value := sum_to_varchar_function(3, :param1) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'sum_to_varchar_function' NODE ***/!!!;
INSERT INTO result_table
VALUES (1, :result_value);
END;
$$;
DECLARE
call_results VARIANT;
BEGIN
CALL
procedure_calling_function(5);
RETURN call_results;
END;
Résultat¶
ID RESULT_COL
1 8
Appel d’UDF dans une requête¶
Lorsqu’un appel de fonction est intégré à une requête, le processus d’invocation devient plus complexe en raison de la limite imposée par Snowflake, qui ne permet pas d’appeler des procédures directement dans les requêtes. Pour surmonter cette limite, l’invocation de la procédure est déplacée en dehors de la requête, et le résultat est assigné à une variable. Cette variable est ensuite référencée dans la requête, ce qui permet d’obtenir une équivalence fonctionnelle. Cette approche permet l’exécution de comportements plus complexes dans le cadre des requêtes Snowflake tout en respectant les contraintes procédurales.
Oracle¶
CREATE OR REPLACE PROCEDURE procedure_calling_function(param1 IN NUMBER)
IS
result_value VARCHAR(200);
result_value2 VARCHAR(200);
BEGIN
SELECT
sum_to_varchar_function(1, param1) AS result_column,
sum_to_varchar_function(2, param1) AS result_column2
INTO result_value, result_value2
FROM example_table ext;
INSERT INTO result_table VALUES (1, result_value);
INSERT INTO result_table VALUES (2, result_value2);
END;
BEGIN
procedure_calling_function(5);
END;
Résultat¶
ID RESULT_COL
1 6
2 7
Exécution de scripts Snowflake¶
CREATE OR REPLACE PROCEDURE procedure_calling_function (param1 NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
result_value VARCHAR(200);
result_value2 VARCHAR(200);
BEGIN
SELECT
sum_to_varchar_function(1, :param1) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'sum_to_varchar_function' NODE ***/!!! AS result_column,
sum_to_varchar_function(2, :param1) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'sum_to_varchar_function' NODE ***/!!! AS result_column2
INTO
:result_value,
:result_value2
FROM
example_table ext;
INSERT INTO result_table
VALUES (1, :result_value);
INSERT INTO result_table
VALUES (2, :result_value2);
END;
$$;
DECLARE
call_results VARIANT;
BEGIN
CALL
procedure_calling_function(5);
RETURN call_results;
END;
Résultat¶
ID RESULT_COL
1 6
2 7
Problèmes connus¶
1. Unsupported Usage of UDFs in Queries with Query Dependencies¶
Lors de l’appel de fonctions définies par l’utilisateur (UDFs) dans des requêtes avec des dépendances de requête, les scénarios impliquant des fonctions intégrées avec des colonnes comme arguments ne sont pas pris en charge. Cette limite est due au fait que les valeurs des colonnes ne sont pas accessibles depuis l’extérieur de la requête. Voici quelques exemples de scénarios non pris en charge :
BEGIN
SELECT
sum_to_varchar_function(ext.col1, ext.col2) -- columns as arguments not supported
INTO
result_value
FROM example_table ext;
END;
\ Les scénarios pris en charge incluent les appels de fonctions avec d’autres types d’arguments tels que des valeurs littérales, des variables externes ou des paramètres. Par exemple :
BEGIN
SELECT
sum_to_varchar_function(100, param1)
INTO
result_value
FROM example_table ext;
END;
Dans les scénarios pris en charge, la fonction peut effectivement être migrée.
EWIs connexes¶
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-FDM-0006: La colonne de type nombre peut ne pas se comporter de la même manière dans Snowflake.
SSC-FDM-0029: La fonction définie par l’utilisateur a été transformée en procédure Snowflake.
WHILE¶
Référence de traduction pour convertir l’instruction Oracle WHILE en instruction Snowflake Scripting
Description¶
L’instruction
WHILELOOPexécute une ou plusieurs instructions alors qu’une condition estTRUE.\ (Référence linguistique Oracle PL/SQL Instruction WHILE).
Syntaxe WHILE Oracle¶
WHILE boolean_expression
LOOP statement... END LOOP [ label ] ;
Syntaxe WHILE Snowflake Scripting¶
WHILE ( <condition> ) { DO | LOOP }
<statement>;
[ <statement>; ... ]
END { WHILE | LOOP } [ <label> ] ;
Le comportement d’Oracle WHILE peut également être modifié à l’aide des instructions :
Modèles d’échantillons de sources¶
Cas simple While¶
Remarque
Ce cas est équivalent sur le plan fonctionnel.
Oracle¶
CREATE TABLE while_testing_table
(
iterator VARCHAR2(5)
);
CREATE OR REPLACE PROCEDURE while_procedure
IS
I NUMBER := 1;
J NUMBER := 10;
BEGIN
WHILE I <> J LOOP
INSERT INTO while_testing_table VALUES(TO_CHAR(I));
I := I+1;
END LOOP;
END;
CALL while_procedure();
SELECT * FROM while_testing_table;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Exécution de scripts Snowflake¶
CREATE OR REPLACE TABLE while_testing_table
(
iterator VARCHAR(5)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
CREATE OR REPLACE PROCEDURE while_procedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
I NUMBER(38, 18) := 1;
J NUMBER(38, 18) := 10;
BEGIN
WHILE (:I <> :J)
--** SSC-PRF-0008 - PERFORMANCE REVIEW - LOOP USAGE **
LOOP
INSERT INTO while_testing_table
VALUES(TO_CHAR(:I));
I := :I +1;
END LOOP;
END;
$$;
CALL while_procedure();
SELECT * FROM
while_testing_table;
Résultat¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Problèmes connus¶
Aucun problème n’a été constaté.
EWIs connexes¶
Pas d’EWIs connexes.