SnowConvert AI – Oracle – PL/SQL in Snowflake Scripting¶
ASSIGNMENT STATEMENT¶
Beschreibung¶
Die ASSIGNMENT-Anweisung setzt den Wert eines Datenelements auf einen gültigen Wert.\ (Oracle PL/SQL-Sprachreferenz – ASSIGNMENT-Anweisung)
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Syntax der ASSIGNMENT-Anweisung von 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
}
Syntax der ASSIGNMENT-Anweisung von Snowflake Scripting¶
LET <variable_name> <type> { DEFAULT | := } <expression> ;
LET <variable_name> { DEFAULT | := } <expression> ;
Bemerkung
LET-Schlüsselwort wird für Zuweisungsanweisungen nicht benötigt, wenn die Variable zuvor deklariert wurde. Weitere Informationen finden Sie in der Dokumentation Snowflake-Zuweisung.
Beispielhafte Quellcode-Muster¶
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;
Ergebnis¶
COL1 |
COL2 |
COL3 |
COL4 |
|---|---|---|---|
1 |
4.2 |
Hello World |
1 |
Snowflake Scripting¶
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;
Ergebnis¶
COL1 |
COL2 |
COL3 |
COL4 |
|---|---|---|---|
1.000000000000000000 |
4.000000000000000000 |
Hello World |
1 |
Warnung
Die Transformation für einige Datentypen muss aktualisiert werden, dies kann zu anderen Ergebnissen führen. Zum Beispiel rundet NUMBER auf NUMBER den Wert und das Dezimalkomma geht verloren. Es gibt bereits ein Work-Element zu diesem Thema.
2. Out Parameter Assignment¶
Weitere Informationen darüber, wie die Ausgabeparameter umgewandelt werden, finden Sie im folgenden Artikel Ausgabeparameter.
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;
Snowflake Scripting¶
--** 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;
$$;
Bekannte Probleme¶
1. Several Unsupported Assignment Statements¶
Derzeit werden Transformationen für Cursor-, Auflistungs-, Datensatz- und benutzerdefinierte Typvariablen von Snow Scripting nicht unterstützt. Daher werden Zuweisungsanweisungen, die diese Variablen verwenden, kommentiert und als nicht unterstützt gekennzeichnet. Die Änderung dieser Variablen in semistrukturierte Daten von Snowflake könnte in einigen Szenarien eine Umgehungsmöglichkeit schaffen.
CALL¶
Beschreibung¶
Es gibt zwei Arten von CALL-Anweisungen in Oracle:
1-CALL-Anweisung:¶
Verwenden Sie die Anweisung
CALL, um eine Routine (eine eigenständige Prozedur oder Funktion oder eine innerhalb eines Typs oder Pakets definierte Prozedur oder Funktion) aus SQL heraus auszuführen. (Oracle SQL Language Reference CALL)
2-Call-Spezifikation:¶
Eine Call-Spezifikation deklariert eine Java-Methode oder ein C-Unterprogramm, so dass es von PL/SQL aus aufgerufen werden kann. (Oracle SQL Language Reference Call Specification)
Die CALL-Spezifikation wird in Snowflake Scripting nicht unterstützt, da sie Teil der Entwicklungsbibliotheken für C und JAVA ist, nicht aber eine SQL-Anweisung, daher wird diese Anweisung nicht transformiert.
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
Keine zugehörigen EWIs.
CASE¶
Übersetzungsreferenz für CASE-Anweisungen
Beschreibung¶
Die Anweisung
CASEwählt aus einer Sequenz von Bedingungen aus und führt eine entsprechende Anweisung aus. Weitere Informationen zu Oracle CASE finden Sie hier.
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Simple Case¶
Syntax der CASE-Anweisung von Oracle¶
[ <<label>> ] CASE case_operand
WHEN boolean_expression THEN statement ;
[ WHEN boolean_expression THEN statement ; ]...
[ ELSE statement [ statement ]... ;
END CASE [ label ] ;
Syntax der CASE-Anweisung von Snowflake Scripting¶
CASE ( <expression_to_match> )
WHEN <expression> THEN
<statement>;
[ <statement>; ... ]
[ WHEN ... ]
[ ELSE
<statement>;
[ <statement>; ... ]
]
END [ CASE ] ;
Searched Case¶
Syntax der CASE-Anweisung von Oracle¶
[ <<label>> ] CASE
WHEN boolean_expression THEN statement ;
[ WHEN boolean_expression THEN statement ; ]...
[ ELSE statement [ statement ]... ;
END CASE [ label ];
Syntax der CASE-Anweisung von Snowflake Scripting¶
CASE
WHEN <boolean_expression> THEN
<statement>;
[ <statement>; ... ]
[ WHEN ... ]
[ ELSE
<statement>;
[ <statement>; ... ]
]
END [ CASE ] ;
Beispielhafte Quellcode-Muster¶
Beispiel einer Hilfstabelle¶
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"}}'
;
Simple Case¶
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;
Ergebnis¶
COL |
|---|
Schlecht |
Keine solche Bewertung |
Ausgezeichnet |
Snowflake Scripting¶
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;
Ergebnis¶
COL |
|---|
Schlecht |
Keine solche Bewertung |
Ausgezeichnet |
Searched Case¶
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;
Ergebnis¶
COL |
|---|
Schlecht |
Keine solche Bewertung |
Ausgezeichnet |
Snowflake Scripting¶
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;
Ergebnis¶
COL |
|---|
Schlecht |
Keine solche Bewertung |
Ausgezeichnet |
Bekannte Probleme¶
1. Labels are not supported in Snowflake Scripting CASE syntax¶
Die Beschriftungen werden je nach ihrer Position auskommentiert oder entfernt.
Zugehörige EWIS¶
SSC-EWI-0094: Label-Deklaration wird nicht unterstützt.
SSC-FDM-0007: Element mit fehlenden Abhängigkeiten.
COMPOUND STATEMENTS¶
Dieser Abschnitt ist eine Übersetzungsspezifikation für die zusammengesetzten Anweisungen
Warnung
Dieser Abschnitt ist noch in Arbeit, die Informationen können sich in Zukunft noch ändern.
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Allgemeine Beschreibung¶
Die Grundeinheit eines PL/SQL-Quellprogramms ist der Block, in dem zusammengehörige Deklarationen und Anweisungen zusammengefasst werden.
Ein PL/SQL-Block wird durch die Schlüsselwörter DECLARE, BEGIN, EXCEPTION, und END definiert. Diese Schlüsselwörter unterteilen den Block in einen deklarativen Teil, einen ausführbaren Teil und einen Teil zur Behandlung von Ausnahmen. Es wird nur der ausführbare Teil benötigt. (PL/SQL Anonyme Blöcke)
Der BEGIN...END-Block in Oracle kann die folgenden Eigenschaften haben:
Verschachtelt sein.
Enthält die Anweisung DECLARE für Variablen.
Gruppieren Sie mehrere SQL oder PL/SQL-Anweisungen.
Oracle-Syntax¶
[DECLARE <Variable declaration>]
BEGIN
<Executable statements>
[EXCEPTION <Exception handler>]
END
Snowflake-Syntax¶
BEGIN
<statement>;
[ <statement>; ... ]
[ EXCEPTION <exception_handler> ]
END;
Bemerkung
In Snowflake kann ein BEGIN/END-Block das Top-Level-Konstrukt innerhalb eines anonymen Blocks sein (Snowflake-Dokumentation).
Beispielhafte Quellcode-Muster¶
1. IF-ELSE block¶
Weitere Informationen zu IF-Anweisungen finden Sie in der folgenden Dokumentation: Übersetzung von SnowConvert AI IF-Anweisungen und Dokumentation zu IF-Anweisungen von Snowflake
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;
Ergebnis¶
Statement processed.
You are an adult.
Snowflake¶
Warnung
Wenn Sie eine Prozedur oder eine benutzerdefinierte Funktion (UDF) aufrufen, müssen Sie Code generieren, um die Äquivalenz als Aufrufergebnisse-Variable zu unterstützen. Wird in diesem Fall zum Drucken der Informationen verwendet.
Sehen Sie sich die [hier](../ Built-in-packages.md#put_line-procedure) verwendete benutzerdefinierte Funktion (UDF) genauer an.
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;
Ergebnis¶
anonymous block
You are an adult.
2. CASE statement¶
Weitere Informationen dazu finden Sie in der folgenden Dokumentation: Dokumentation zu SnowConvert AI CASE-Anweisungen und Dokumentation zur CASE-Anweisung von 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;
Ergebnis¶
Statement processed.
Tuesday
Snowflake¶
Warnung
Wenn Sie eine Prozedur oder eine benutzerdefinierte Funktion (UDF) aufrufen, müssen Sie Code generieren, um die Äquivalenz als Aufrufergebnisse-Variable zu unterstützen. Wird in diesem Fall zum Drucken der Informationen verwendet.
Sehen Sie sich die [hier](../ Built-in-packages.md#put_line-procedure) verwendete benutzerdefinierte Funktion (UDF) genauer an.
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;
Ergebnis¶
anonymous block
Tuesday
3. LOOP statements¶
Weitere Informationen dazu finden Sie in der folgenden Dokumentation: Dokumentation zu SnowConvert AI FOR LOOP-Anweisungen, Dokumentation zu LOOP-Anweisungen und Dokumentation zu FOR-Anweisungen von Snowflake.
Oracle¶
BEGIN
FOR i IN 1..10 LOOP
NULL;
END LOOP;
END;
Ergebnis¶
Statement processed.
Snowflake¶
Erste Registerkarte¶
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;
Ergebnis¶
anonymous block
4. Procedure call and OUTPUT parameters¶
Ein anonymer Block in Oracle kann Aufrufe von Prozeduren enthalten. Darüber hinaus kann die folgende Dokumentation hilfreich sein: Dokumentation zu SnowConvert AI-Prozeduren.
Im folgenden Beispiel werden die OUT-Parameter verwendet; Informationen zu der aktuellen Transformation finden Sie hier: SnowConvert AI OUTPUT-Parameter.
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;
/
Ergebnis¶
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;
Ergebnis¶
anonymous block
The sum of 10 and 20 is 30
5. Alter session¶
Weitere Informationen finden Sie in der folgenden Dokumentation: Dokumentation zu ALTER SESSION.
Beachten Sie, dass in Oracle der Block BEGIN...END die Anweisung EXECUTE IMMEDIATE verwenden sollte, um die Anweisungen Alter Session auszuführen.
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;
Ergebnis¶
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;
Ergebnis¶
anonymous block
Done
6. Cursors¶
Das folgende Beispiel zeigt die Verwendung von CURSOR innerhalb eines BEGIN...END-Blocks. Weitere Informationen finden Sie in der folgenden Dokumentation: Dokumentation zu CURSOR.
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;
Ergebnis¶
Statement processed.
NameA NameZ
Snowflake¶
Warnung
Wenn Sie eine Prozedur oder eine benutzerdefinierte Funktion (UDF) aufrufen, müssen Sie Code generieren, um die Äquivalenz als Aufrufergebnisse-Variable zu unterstützen. Wird in diesem Fall zum Drucken der Informationen verwendet.
Sehen Sie sich die [hier](../ Built-in-packages.md#put_line-procedure) verwendete benutzerdefinierte Funktion (UDF) genauer an.
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;
Ergebnis¶
anonymous block
NameA NameZ
7. Select statements¶
Weitere Informationen finden Sie in der folgenden Dokumentation: Dokumentation zu ‚SELECT‘-Anweisungen.
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;
Ergebnis¶
Statement processed.
2
Snowflake¶
Warnung
Wenn Sie eine Prozedur oder eine benutzerdefinierte Funktion (UDF) aufrufen, müssen Sie Code generieren, um die Äquivalenz als Aufrufergebnisse-Variable zu unterstützen. Wird in diesem Fall zum Drucken der Informationen verwendet.
Sehen Sie sich die [hier](../ Built-in-packages.md#put_line-procedure) verwendete benutzerdefinierte Funktion (UDF) genauer an.
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;
Ergebnis¶
anonymous block
2
8. Join Statements¶
Weitere Informationen dazu finden Sie in der folgenden Dokumentation: Dokumentation zu JOIN-Anweisungen.
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;
Ergebnis¶
Statement processed.
7
Snowflake¶
Warnung
Wenn Sie eine Prozedur oder eine benutzerdefinierte Funktion (UDF) aufrufen, müssen Sie Code generieren, um die Äquivalenz als Aufrufergebnisse-Variable zu unterstützen. Wird in diesem Fall zum Drucken der Informationen verwendet.
Sehen Sie sich die [hier](../ Built-in-packages.md#put_line-procedure) verwendete benutzerdefinierte Funktion (UDF) genauer an.
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;
Ergebnis¶
Statement processed.
ORA-01476: divisor is equal to zero
Snowflake¶
Warnung
ZERO_DIVIDE-Ausnahme wird in Snowflake nicht unterstützt.
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;
Ergebnis¶
anonymous block
Division by zero
Bekannte Probleme¶
Nicht unterstützte GOTO-Anweisungen in Oracle.
Ausnahmen, die GOTO-Anweisungen verwenden, können ebenfalls betroffen sein.
Die Cursor-Funktionalität kann im Rahmen der derzeitigen Übersetzungsbeschränkungen angepasst werden.
Zugehörige EWIs¶
SSC-EWI-0027:Die folgende Anweisung verwendet eine Variable/ein Literal mit einer ungültigen Abfrage und wird nicht ausgeführt.
SSC-EWI-OR0036: Bei Problemen mit der Auflösung von Typen verhält sich die arithmetische Operation zwischen Zeichenfolge und Datum möglicherweise nicht korrekt.
SSC-FDM-OR0035: DBMS_OUTPUT. UDF-Implementierung von PUTLINE-Prüfung.
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-PRF-0004: Diese Anweisung hat Verwendungen für Cursor-FOR-Schleife.
SSC-EWI-0030: Die folgende Anweisung enthält Verwendungen von dynamischem SQL.
CONTINUE¶
Übersetzungsreferenz zur Konvertierung der CONTINUE-Anweisung von Oracle in Snowflake Scripting
Beschreibung¶
Die
CONTINUE-Anweisung beendet die aktuelle Iteration einer Schleife, entweder bedingt oder ohne Bedingungen, und übergibt die Kontrolle an die nächste Iteration entweder der aktuellen Schleife oder einer umschließenden, beschrifteten Schleife.\ (Oracle PL/SQL-Sprachreferenz – CONTINUE-Anweisung)
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Syntax der CONTINUE-Anweisung von Oracle¶
CONTINUE [ label ] [ WHEN boolean_expression ] ;
Syntax der CONTINUE-Anweisung von Snowflake Scripting¶
{ CONTINUE | ITERATE } [ <label> ] ;
Beispielhafte Quellcode-Muster¶
1. Simple Continue¶
Der Code überspringt die Anweisung INSERT, indem er CONTINUE verwendet.
Hinweis
Dieser Fall ist funktionell gleichwertig.
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;
Ergebnis¶
ITERATOR |
|---|
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
2. Continue with condition¶
Der Code überspringt das Einfügen gerader Zahlen durch die Verwendung von CONTINUE.
Bemerkung
Dieser Fall ist funktionell nicht gleichwertig, aber Sie können die Bedingung in eine IF-Anweisung umwandeln.
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;
Ergebnis¶
ITERATOR |
|---|
1 |
3 |
5 |
7 |
9 |
11 |
13 |
15 |
17 |
19 |
21 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
1 |
3 |
5 |
7 |
9 |
11 |
13 |
15 |
17 |
19 |
21 |
3. Continue with label and condition¶
Der Code überspringt Zeile 19, und die innere Schleife wird nur einmal ausgeführt, da CONTINUE über das Label immer zur äußeren Schleife springt.
Hinweis
Dieser Fall ist funktionell äquivalent zur Anwendung des gleichen Prozesses wie das vorherige Beispiel.
Bemerkung
Beachten Sie, dass die Labels auskommentiert werden.
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;
Ergebnis¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
I2 |
I3 |
I4 |
I5 |
I6 |
I7 |
I8 |
I9 |
I10 |
I11 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
I2 |
I3 |
I4 |
I5 |
I6 |
I7 |
I8 |
I9 |
I10 |
I11 |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
SSC-EWI-0094: Label-Deklaration wird nicht unterstützt.
DECLARE¶
Übersetzungsreferenz zur Konvertierung der DECLARE-Anweisung von Oracle in Snowflake Scripting
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Die Oracle DECLARE-Anweisung ist ein optionaler Teil der PL/SQL Blockanweisung. Es ermöglicht die Erstellung von Variablen, Konstanten, Prozedurendeklarationen und -definitionen, Funktionsdeklarationen und -definitionen, Ausnahmen, Cursors, Typen und vielen anderen Anweisungen. Weitere Informationen zu Oracle DECLARE finden Sie hier.
Syntax der DECLARE-Anweisung von 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 ] ;
Syntax der DECLARE-Anweisung von 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> ] ;
Beispielhafte Quellcode-Muster¶
Variablendeklaration¶
Syntax der Variablendeklaration von Oracle¶
variable_declaration::=
variable datatype [ [ NOT NULL] {:= | DEFAULT} expression ] ;
Syntax der Variablendeklaration in 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;
Snowflake Scripting¶
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;
$$;
Konstanten-Deklaration¶
Warnung
Konstanten werden in Snowflake Scripting nicht unterstützt, aber sie werden in Variablen umgewandelt, um die Verhaltensweise zu simulieren.
Syntax der Konstantendeklaration von Oracle¶
constant_declaration::=
constant CONSTANT datatype [NOT NULL] { := | DEFAULT } expression ;
Syntax der Variablendeklaration in 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;
Snowflake Scripting¶
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;
$$;
Cursordeklaration¶
Syntax der Cursordeklaration von 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
}
Syntax der Cursordeklaration von Snowflake Scripting¶
<cursor_name> CURSOR [ ( <argument> [, <argument> ... ] ) ]
FOR <query> ;
Gefahr
Die Oracle _ Cursordeklaration _ ist nicht erforderlich, so dass sie im Ausgabecode auskommentiert werden kann. Die _ Cursordefinition _ wird anstelle von verwendet und in die Snowflake Scripting _ Cursordeklaration _ umgewandelt. Lesen Sie bitte den Abschnitt CURSOR um weitere Informationen über die Cursordefinition zu erhalten.
Ausnahmedeklaration¶
Auf die Ausnahmendeklaration kann manchmal auch die Initialisierung der Ausnahme folgen. Die aktuelle Transformation nimmt beide und fügt sie in die Snowflake Scripting-Ausnahmendeklaration ein. Das Original PRAGMA EXCEPTION_INIT wird auskommentiert.
Syntax der Ausnahmedeklaration von Oracle¶
exception_declaration::= exception EXCEPTION;
PRAGMA EXCEPTION_INIT ( exception, error_code ) ;
Syntax der Ausnahmedeklaration von 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;
Snowflake Scripting¶
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;
$$;
Nicht unterstützte Fälle¶
Die folgenden Oracle-Deklarationsanweisungen werden vom Snowflake Scripting-Deklarationsblock nicht unterstützt:
Deklaration von Cursorvariablen
Deklaration von Sammlungsvariablen
Deklaration von Datensatzvariablen
Typdefinition (alle Varianten)
Deklaration und Definition von Funktionen
Deklaration und Definition von Prozeduren
Bekannte Probleme¶
1. The variable declarations with NOT NULL constraints are not supported by Snow Scripting.¶
Die Erstellung von Variablen mit der Einschränkung NOT NULL führt in Snow Scripting zu einem Fehler.
2. The cursor declaration has no equivalent to Snowflake Scripting.¶
Die Oracle-Cursordeklaration ist nutzlos, daher kann sie im Ausgabecode auskommentiert werden. Die Cursordefinition wird stattdessen verwendet und in die Snowflake Scripting Cursordeklaration umgewandelt.
3. The exception code exceeds Snowflake Scripting limits.¶
Der Oracle-Ausnahmecode wird entfernt, wenn er die Grenzen des Snowflake Scripting-Codes überschreitet. Der Ausnahmecode muss eine Ganzzahl zwischen -20000 und -20999 sein.
3. The not supported cases.¶
Es gibt einige Oracle-Deklarationsanweisungen, die vom Snowflake Scripting-Deklarationsblock nicht unterstützt werden, so dass sie möglicherweise auskommentiert werden und eine Warnung hinzugefügt wird.
Zugehörige EWIS¶
SSC-EWI-OR0051: PRAGMA EXCEPTION_INIT wird nicht unterstützt.
SSC-EWI-OR0099: Der Ausnahmecode überschreitet die Snowflake Scripting-Beschränkung
SSC-FDM-0016: Konstanten werden von Snowflake Scripting nicht unterstützt. Sie wurde in eine Variable umgewandelt.
SSC-FDM-OR0025: „Not Null“-Einschränkung wird in Snowflake-Prozeduren nicht unterstützt.
DEFAULT PARAMETERS¶
In diesem Artikel geht es um die aktuelle Transformation der Standardparameter und wie deren Funktionalität emuliert wird.
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Ein Standardparameter ist ein Parameter, der einen Wert hat, falls im Prozedur- oder Funktionsaufruf kein Argument übergeben wird. Da Snowflake keine Standardparameter unterstützt, fügt SnowConvert AI den Standardwert in den Prozedur- oder Funktionsaufruf ein.
In der Deklaration wird die DEFAULT VALUE-Klausel des Parameters entfernt. Beide Syntaxen, das Symbol : = und die Klausel DEFAULT werden unterstützt.
Beispielhafte Quellcode-Muster¶
Beispiel für Hilfscode¶
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"}}'
;
Standardparameter-Deklaration¶
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;
Snowflake Scripting¶
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;
$$;
Aufrufen von Prozeduren mit Standardparametern¶
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;
Snowflake Scripting¶
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;
$$;
Um zu überprüfen, ob die Funktionalität korrekt emuliert wird, führt die folgende Abfrage die Prozedur und SELECT aus der zuvor erwähnten Tabelle aus.
Oracle¶
CALL PROC_WITH_DEFAULT_CALLS();
SELECT * FROM TABLE1;
Ergebnis¶
COL1 |
COL2 |
|---|---|
10 |
15 |
10 |
1 |
10 |
15 |
10 |
2 |
1 |
2 |
Snowflake Scripting¶
CALL PROC_WITH_DEFAULT_CALLS();
SELECT * FROM TABLE1;
Ergebnis¶
COL1 |
COL2 |
|---|---|
10 |
15 |
10 |
1 |
10 |
15 |
10 |
2 |
1 |
2 |
Aufrufen von Prozeduren mit benannten Argumenten und Standardparametern¶
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;
Snowflake Scripting¶
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;
$$;
Um zu überprüfen, ob die Funktionalität korrekt emuliert wird, führt die folgende Abfrage die Prozedur und SELECT aus der zuvor erwähnten Tabelle aus.
Oracle¶
CALL PROC_WITH_DEFAULT_CALLS2();
SELECT * FROM TABLE2;
Ergebnis¶
COL1 |
COL2 |
COL3 |
|---|---|---|
10 |
20 |
30 |
10 |
20 |
30 |
20 |
30 |
10 |
100 |
30 |
10 |
100 |
10 |
30 |
100 |
10 |
1000 |
Snowflake Scripting¶
CALL PROC_WITH_DEFAULT_CALLS2();
SELECT * FROM TABLE2;
Ergebnis¶
COL1 |
COL2 |
COL3 |
|---|---|---|
10 |
20 |
30 |
10 |
20 |
30 |
20 |
30 |
10 |
100 |
30 |
10 |
100 |
10 |
30 |
100 |
10 |
1000 |
Bekannte Probleme¶
1. Keine Probleme gefunden
Zugehörige EWIs¶
Keine zugehörigen EWIs.
EXECUTE IMMEDIATE¶
Übersetzungsreferenz zur Konvertierung der EXECUTE IMMEDIATE-Anweisung von Oracle in Snowflake Scripting
Beschreibung¶
Die Anweisung
EXECUTEIMMEDIATEerstellt und führt eine dynamische Anweisung SQL in einer einzigen Operation aus.Native dynamische SQL verwendet die Anweisung
EXECUTEIMMEDIATE, um die meisten dynamischen SQL-Anweisungen zu verarbeiten. (Oracle PL/SQL Language Reference EXECUTE IMMEDIATE Statement)
EXECUTE IMMEDIATE-Syntax von 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 unterstützt diese Anweisung, wenn auch mit einigen funktionalen Unterschieden. Weitere Informationen über das Snowflake-Pendant finden Sie in der Snowflake-Dokumentation EXECUTE IMMEDIATE.
EXECUTE IMMEDIATE-Syntax von Snowflake Scripting¶
EXECUTE IMMEDIATE <dynamic statement> ;
dynamic statement::= {'<string literal>' | <variable> | $<session variable>}
Beispielhafte Quellcode-Muster¶
In den nächsten Beispielen wird eine Tabelle erstellt und versucht, die Tabelle mit Execute Immediate zu löschen.
Verwendung einer fest codierten Zeichenfolge¶
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;
Snowflake Scripting¶
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;
Speichern der Zeichenfolge in einer Variablen¶
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;
Snowflake Scripting¶
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;
Verkettung für Parameter in dynamischen Anweisungen¶
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;
Snowflake Scripting¶
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 der USING-Klausel¶
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;
Ergebnisse¶
COL1 |
|---|
1 |
Snowflake Scripting¶
Bemerkung
Bitte beachten Sie, dass Parameter in der USING-Klausel in Snowflake Scripting in Klammern gesetzt werden müssen.
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;
Ergebnisse¶
COL1 |
|---|
1 |
Bekannte Probleme¶
1. Immediate Execution results cannot be stored in variables.¶
SnowScripting unterstützt weder INTO- noch BULK COLLECT INTO-Klauseln. Aus diesem Grund müssen die Ergebnisse auf anderem Wege übermittelt werden.
2. Numeric Placeholders¶
Numerische Namen für Platzhalter werden derzeit nicht von SnowConvert AI erkannt, aber es gibt ein Work-Element, um dieses Problem zu beheben.
3. Argument Expressions are not supported by Snowflake Scripting¶
In Oracle ist es möglich, Ausdrücke als Argumente für die verwendende Klausel zu verwenden. Dies wird jedoch von Snowflake Scripting nicht unterstützt und ist daher auskommentiert.
4. Dynamic SQL Execution queries may be marked incorrectly as non-runnable.¶
In einigen Szenarien kann eine Ausführungsanweisung unabhängig davon, ob sie sicher oder nicht sicher ist, kommentiert werden. Bitte berücksichtigen Sie dies:
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;
Snowflake Scripting¶
Bemerkung
Bitte beachten Sie, dass Parameter in der USING-Klausel in Snowflake Scripting in Klammern gesetzt werden müssen.
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;
$$;
Zugehörige EWIs¶
SSC-EWI-0027: Variable mit ungültiger Abfrage.
SSC-EWI-0030: Die folgende Anweisung enthält Verwendungen von dynamischem SQL.
EXIT¶
Übersetzungsreferenz zur Konvertierung der EXIT-Anweisung von Oracle in Snowflake Scripting
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Die
EXIT-Anweisung beendet die aktuelle Iteration einer Schleife, entweder bedingt oder ohne Bedingungen, und übergibt die Kontrolle an das Ende entweder der aktuellen Schleife oder einer umschließenden, beschrifteten Schleife.\ (Oracle PL/SQL-Sprachreferenz – EXIT-Anweisung)
Syntax der EXIT-Anweisung von Oracle¶
EXIT [ label ] [ WHEN boolean_expression ] ;
Syntax der EXIT-Anweisung von Snowflake Scripting¶
{ BREAK | EXIT } [ <label> ] ;
Beispielhafte Quellcode-Muster¶
Bemerkung
Beachten Sie, dass Sie EXITmit BREAKändern können und alles wie gewohnt funktioniert.
1. Simple Exit¶
Der Code überspringt die Anweisung INSERT, indem er EXIT verwendet.
Hinweis
Dieser Fall ist funktionell gleichwertig.
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;
Ergebnis¶
ITERATOR |
|---|
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
2. Exit with condition¶
Der Code verlässt die Schleife, wenn der Iterator größer als 5 ist.
Hinweis
Dieser Fall ist funktionell gleichwertig, indem die Bedingung in eine IF- Anweisung umgewandelt wird.
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
3. Exit with label and condition¶
Der Code unterbricht beide Schleifen, indem er die Anweisung EXIT verwendet, die auf die äußere Schleife verweist.
Hinweis
Dieser Fall ist funktionell äquivalent zur Anwendung des gleichen Prozesses wie das vorherige Beispiel.
Bemerkung
Beachten Sie, dass die Labels auskommentiert werden.
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;
Ergebnis¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
I1 |
K1 |
K2 |
K3 |
K4 |
K5 |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
SSC-EWI-0094: Label-Deklaration wird nicht unterstützt.
EXPRESSIONS¶
Übersetzungsreferenz von Oracle-Ausdrücken in Snow Scripting
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
In der folgenden Tabelle finden Sie eine Zusammenfassung, wie Sie die verschiedenen Oracle-Ausdruckstypen in Snow Scripting umwandeln können.
Syntax |
Status der Konvertierung |
Notizen |
|---|---|---|
Teilweise |
||
Teilweise |
||
Teilweise |
||
Teilweise |
||
Vollständig |
N/A |
|
Vollständig |
N/A |
|
Nicht übersetzt |
Snowflake hat kein natives Äquivalent für Oracle-Sammlungen. Siehe Sammlungen und Datensätze. |
|
Nicht übersetzt |
Snowflake hat kein natives Äquivalent für Oracle-Datensatztypen. Siehe Sammlungen und Datensätze. |
Teilweise unterstützte gemeinsame Szenarien¶
Oracle-Konstanten¶
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;
Ergebnis¶
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;
Ergebnis¶
COL |
|---|
CONSTANT-TEXT |
Nicht unterstützte numerische Ausdrücke¶
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;
Ergebnis¶
COL |
|---|
4 |
104 |
11 |
3 |
Nicht unterstützte boolesche Ausdrücke¶
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;
Zugehörige EWIs.¶
SSC-FDM-0016: Konstanten werden von Snowflake Scripting nicht unterstützt. Sie wurde in eine Variable umgewandelt.
FOR LOOP¶
Beschreibung¶
Bei jeder Iteration der Anweisung
FORLOOPwerden die Anweisungen ausgeführt, der Index wird entweder erhöht oder verringert und die Kontrolle kehrt an den Anfang der Schleife zurück. (Oracle PL/SQL Language Reference FOR LOOP Statement).
Oracle-Syntax¶
FOR
pls_identifier [ MUTABLE | IMMUTABLE ] [ constrained_type ]
[ , iterand_decl ]
IN
[ REVERSE ] iteration_control pred_clause_seq
[, qual_iteration_ctl]...
LOOP
statement...
END LOOP [ label ] ;
Snowflake Scripting-Syntax¶
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP }
statement;
[ statement; ... ]
END { FOR | LOOP } [ <label> ] ;
Snowflake Scripting unterstützt FOR LOOP, das eine bestimmte Anzahl von Schleifen durchläuft. Die Ober- und Untergrenzen müssen INTEGER sein. Weitere Informationen finden Sie in der Snowflake Scripting-Dokumentation.
Die Verhaltensweise von Oracle FOR LOOP kann auch durch die Verwendung der Anweisungen geändert werden:
Beispielhafte Quellcode-Muster¶
1. FOR LOOP¶
Hinweis
Dieser Fall ist funktionell gleichwertig.
Oracle-Beispiel für FOR LOOP¶
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;
Snowflake Scripting-Beispiel für FOR LOOP¶
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¶
Oracle-Beispiel für FOR LOOP¶
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;
Snowflake Scripting-Beispiel für FOR LOOP¶
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¶
Oracle-Beispiel für FOR LOOP¶
CREATE OR REPLACE PROCEDURE P3
AS
BEGIN
FOR i IN REVERSE 1..3,
REVERSE i+5..i+7
LOOP
NULL;
END LOOP;
END;
Snowflake Scripting-Beispiel für FOR LOOP¶
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¶
Oracle-Beispiel für FOR LOOP¶
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;
Snowflake Scripting-Beispiel für FOR LOOP¶
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;
$$;
Warnung
Die Transformation für benutzerdefinierte Typen wird für Snowflake Scripting derzeit nicht unterstützt.
Bekannte Probleme¶
1. For With Multiple Conditions¶
Oracle erlaubt mehrere Bedingungen in einer einzigen FOR LOOP, Snowflake Scripting hingegen erlaubt nur eine Bedingung pro FOR LOOP. Nur die erste Bedingung wird migriert und die anderen werden bei der Transformation ignoriert. Prüfen Sie SSC-FDM-OR0022.
Oracle¶
FOR i IN REVERSE 1..3,
REVERSE i+5..i+7
LOOP
NULL;
END LOOP;
Snowflake Scripting-Beispiel für FOR LOOP¶
--** 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. Veränderliche vs. unveränderliche Zählervariable
Oracle erlaubt es, den Wert der Variable FOR LOOP innerhalb der Schleife zu ändern. Die aktuelle Dokumentation enthält diese Funktion, aber Snowflake empfiehlt, dies zu vermeiden. Das Ändern des Werts dieser Variable kann zu fehlerhaften Ergebnissen bei Snowflake Scripting führen.
3. Ganzzahl vs. Float-Zahl für Ober- oder Untergrenze
Snowflake Scripting erlaubt nur den Typ INTEGER oder einen Ausdruck, der zu INTEGER als Begrenzung für die FOR LOOP-Bedingung ausgewertet wird. Gleitende Zahlen werden auf- oder abgerundet und verändern die ursprüngliche Begrenzung.
4. Von Oracle nicht unterstützte Klauseln
Oracle erlaubt zusätzliche Klauseln für die FOR LOOP-Bedingung. Wie die BY-Klausel für ein schrittweises Inkrement in der Bedingung. Und die WHILE- und WHEN-Klausel für boolesche Ausdrücke. Diese zusätzlichen Klauseln werden in Snowflake Scripting nicht unterstützt und bei der Transformation ignoriert. Überprüfen Sie SSC-EWI-OR0101.
Oracle¶
FOR i IN 5..15 BY 5 LOOP
NULL;
END LOOP;
Snowflake Scripting¶
!!!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. Nicht unterstützte Formate
Oracle erlaubt verschiedene Arten von Bedingungen für FOR LOOP. Es unterstützt boolesche Ausdrücke, Sammlungen, Datensätze … Snowflake Scripting unterstützt jedoch nur FOR LOOP mit definierten Ganzzahlen als Begrenzungen. Alle anderen Formate sind als nicht unterstützt gekennzeichnet und erfordern zusätzlichen manuellen Aufwand für die Umwandlung. Überprüfen Sie SSC-EWI-OR0103.
Zugehörige EWIs¶
SSC-EWI-0058: Die Funktionalität wird derzeit nicht von Snowflake Scripting unterstützt.
SSC-EWI-0062: Die Verwendung des CUSTOM-Typs wurde in ‚variant‘ geändert.
SSC-EWI-OR0100: „For Loop With Multiple Conditions“ wird derzeit von Snowflake Scripting nicht unterstützt. Es wird nur die erste Bedingung verwendet.
SSC-EWI-OR0101: Eine bestimmte For-Loop-Klausel wird derzeit von Snowflake Scripting nicht unterstützt.
SSC-EWI-OR0103: Das For-Loop-Format wird derzeit von Snowflake Scripting nicht unterstützt.
FORALL¶
Beschreibung¶
Die Anweisung
FORALLführt eine Anweisung DML mehrfach aus, mit unterschiedlichen Werten in denVALUES- undWHERE-Klauseln. (Oracle PL/SQL Language Reference FORALL Statement).
Oracle-Syntax¶
FORALL index IN bounds_clause [ SAVE ] [ EXCEPTIONS ] dml_statement ;
Warnung
Snowflake Scripting ist nicht direkt gleichwertig mit der Anweisung FORALL, kann aber mit verschiedenen Umgehungsmöglichkeiten emuliert werden, um eine funktionale Gleichwertigkeit zu erreichen.
Beispielhafte Quellcode-Muster¶
Datenkonfiguration¶
Oracle¶
Tabellen 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);
Tabellen 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¶
Tabellen 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);
Tabellen 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¶
Hinweis
Die drei folgenden Fälle haben die gleiche Transformation zu Snowflake Scripting und sind funktional gleichwertig.
Quelle¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|
1| 2|
1| 2|
2| 3|
3| 4|
4| 5|
5| 6|
Snowflake¶
FORALL mit Sammlung von Datensätzen¶
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;
$$;
Ergebnisse¶
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 |
Bemerkung
Die EWIs SSC-PRF-0001 und SSC-PRF-0003 werden in jedem FETCH BULK COLLECT-Vorkommen in die FORALL-Anweisung eingefügt.
2. FORALL With INSERT INTO¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
Mit 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;
Mit 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;
Ergebnisse von INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
1 |
2 |
Ergebnisse von UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2. |
Snowflake¶
Mit 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;
$$;
Mit 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;
$$;
Ergebnisse von 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 |
Ergebnisse von UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
4. FORALL With Record of Collections¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent in 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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
7. FORALL With Parametrized Cursors¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
8. FORALL Without LOOPS¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
10. FORALL With DELETE Statements¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
no data found
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
Query produced no results
11. FORALL With PACKAGE References¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
10 |
10 |
Snowflake¶
FORALL-Äquivalent¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
10.000000000000000000 |
10.000000000000000000 |
Warnung
Die obige Transformation funktioniert nur, wenn die im Paket definierte Variable ein Datensatz von Collections ist.
12. FORALL With MERGE Statements¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
4 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
2.000000000000000000 |
3.000000000000000000 |
3.000000000000000000 |
4.000000000000000000 |
4.000000000000000000 |
5.000000000000000000 |
5.000000000000000000 |
6.000000000000000000 |
1.000000000000000000 |
4.000000000000000000 |
Warnung
Die obige Transformation funktioniert nur, wenn die Anweisung SELECT innerhalb von MERGE eine Auswahl aus der Tabelle DUAL trifft.
13. Default FORALL transformation¶
Bemerkung
Möglicherweise sind auch die Bulk Cursor-Hilfefunktionen für Sie von Interesse.
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
--** 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;
$$;
Ergebnisse¶
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 |
Bemerkung
Diese Transformation wird nur durchgeführt, wenn keine der zuvor genannten Transformationen möglich ist.
14. Multiple FORALL inside a LOOP clause¶
Bemerkung
Dieses Muster findet Anwendung, wenn es mehr als eine FORALL in derselben Prozedur gibt und diese die folgende Struktur aufweist.
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
15. Multiple FORALL inside different LOOP clauses¶
Bemerkung
Dieses Muster findet Anwendung, wenn es mehr als eine FORALL in derselben Prozedur gibt und diese die folgende Struktur aufweist.
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
54321 |
2 |
54321 |
3 |
54321 |
4 |
54321 |
5 |
54321 |
6 |
16. FORALL with MERGE INTO with LOG ERRORS¶
Warnung
Dieses Muster ist noch nicht implementiert
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¶
Warnung
Dieses Muster ist noch nicht implementiert
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;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
SSC-EWI-0030: Die folgende Anweisung enthält Verwendungen von dynamischem SQL.
[SSC-EWI-0036](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0036): Datentyp in einen anderen Datentyp konvertiert.
[SSC-EWI-0056](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0056): Typ erstellen wird nicht unterstützt.
SSC-EWI-0058: Die Funktionalität wird derzeit nicht von Snowflake Scripting unterstützt.
SSC-EWI-0062: Die Verwendung des CUSTOM-Typs wurde in ‚variant‘ geändert.
SSC-EWI-OR0049: Paketkonstanten in zustandsabhängigen Paketen werden noch nicht unterstützt.
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-FDM-0015: Referenzierter kundenspezifischer Typ in der Abfrage nicht gefunden.
SSC-PRF-0001: Diese Anweisung umfasst die Verwendung von Cursor-Fetch-Bulk-Vorgängen.
SSC-PRF-0003: Das Abrufen innerhalb einer Schleife wird als komplexes Muster betrachtet; dies kann die Leistung von Snowflake beeinträchtigen.
IF¶
Beschreibung¶
Die Anweisung IF führt eine Sequenz von einer oder mehreren Anweisungen aus oder überspringt sie, je nach dem Wert eines BOOLEAN-Ausdrucks. Weitere Informationen zu Oracle IF finden Sie hier.
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;
Beispielhafte Quellcode-Muster¶
Beispiel einer Hilfstabelle¶
CREATE TABLE if_table(col1 varchar(30));
CREATE OR REPLACE TABLE PUBLIC.if_table (col1 varchar(30));
Mögliche IF Variationen¶
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;
Ergebnis 1¶
COL1 |
|---|
ein/e |
Ergebnis 2¶
COL1 |
|---|
Unerwartete Eingabe. |
Ergebnis 3¶
COL1 |
|---|
drei |
Ergebnis 4¶
COL1 |
|---|
Unerwartete Eingabe. |
Snowflake Scripting¶
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;
Ergebnis 1¶
COL1 |
|---|
ein/e |
Ergebnis 2¶
COL1 |
|---|
Unerwartete Eingabe. |
Ergebnis 3¶
COL1 |
|---|
drei |
Ergebnis 4¶
COL1 |
|---|
Unerwartete Eingabe. |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIS¶
Keine zugehörigen EWIs.
IS EMPTY¶
Dies ist eine Übersetzungsreferenz für die Konvertierung der IS EMPTY-Anweisung von Oracle in Snowflake
Warnung
Dieser Abschnitt ist noch in Arbeit; die Informationen können sich in Zukunft ändern.
Beschreibung¶
Verwenden Sie die Bedingungen IS [NOT] EMPTY, um zu testen, ob eine angegebene verschachtelte Tabelle leer ist, unabhängig davon, ob irgendwelche Elemente der Sammlung NULL sind. (Dokumentation).
Oracle-Syntax¶
nested_table IS [ NOT ] EMPTY
Beispielhafte Quellcode-Muster¶
Oracle¶
Das folgende Beispiel zeigt die Verwendung der Anweisung IS EMPTY. Die Anweisung wird auf eine verschachtelte Tabelle angewendet, die eine UDT als Definitionstyp verwendet. Die Ausgabe zeigt die Namen der Mitarbeiter an, die keine Telefonnummer haben.
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;
Ausgabe¶
EMP_NAME |
|---|
Jane Smith |
Snowflake¶
Die unten gezeigte Snowflake-Abfrage ist die Entsprechung der Funktionalität der Anweisung IS EMPTY. Insbesondere die Anweisung IS EMPTY unterscheidet zwischen einem NULL- und einem EMPTY-Objekt.
Beachten Sie, dass die benutzerdefinierten Typen in VARIANT umgewandelt werden. Der Typ VARIANT in Snowflake ist in der Lage, Objekte und Arrays zu speichern. Da es sich bei einer verschachtelten Tabelle um eine Sequenz von Informationen handelt, ist der Typ ARRAY der geeignetste Typ, um sie neu zu definieren und zu überprüfen, ob das Objekt ARRAY leer ist.
Die ARRAY_SIZE äquivalente Lösung erlaubt auch die Frage nach der Nullbarkeit der verschachtelten Tabelle (transformiert in VARIANT). Mit anderen Worten, der Typ VARIANT kann auch NULLs und leere ARRAYs speichern.
!!!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;
Ausgabe¶
EMP_NAME |
|---|
Jane Smith |
Andere mögliche Kombinationen¶
| Description | Oracle | Snowflake |
|---|---|---|
| Ask for a IS NOT EMPTY | | |
| Ask for NULL instead of EMPTY | | |
Bekannte Probleme¶
1. Benutzerdefinierte Typen werden in den Typ VARIANT umgewandelt.¶
Da benutzerdefinierte Typen nicht unterstützt werden, werden sie in Variantentypen umgewandelt, die unter Umständen manuellen Aufwand erfordern, um einige Funktionalitäten zu gewährleisten.
Auf der folgenden Seite finden Sie weitere Informationen:
2. Verschachtelte Tabellen werden nicht unterstützt.¶
Verschachtelte Tabellen werden derzeit nicht unterstützt. Der beste Ansatz auf der Grundlage dieser Äquivalenz ist, verschachtelte Tabellen als Variant zu behandeln, aber Arrays mit JSON-Daten darin zu deklarieren und die Snowflake-Funktion PARSE_JSON auszuführen, um die verschachtelten Informationen aufzufüllen.
Auf den folgenden Seiten finden Sie weitere Informationen:
3. INSERT-Anweisungen werden für benutzerdefinierte Typen nicht unterstützt.¶
Da benutzerdefinierte Typen nicht unterstützt werden, werden auch die INSERT-Anweisungen für diese Typen nicht unterstützt. Speziell in verschachtelten Tabellen muss die Anweisung INSERT INTO... VALUES in INSERT INTO...SELECT geändert werden, da die Funktion ARRAY_CONSTRUCT in diesem Muster verwendet werden soll.
Auf der folgenden Seite finden Sie weitere Informationen:
4. Die Logik sollte an ARRAY-Typen angepasst werden.¶
Da die verschachtelten Tabellen gleichwertig in VARIANT umgewandelt werden und sich wie ARRAYsverhalten sollten, müssen die Funktionalität und Logik der Implementierung von Prozeduren und der Interaktion mit den Daten angepasst werden.
Sehen Sie sich die folgenden Beispiele an:
4.1 Gleichwertigkeit der Prozeduren¶
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;
$$;
Ausgabe¶
PROC1 |
|---|
IS EMPTY |
4.2 SELECT-Anweisungen¶
Die Ausgaben können von den Tabellen auf ARRAYs abweichen.
Oracle¶
SELECT
t.*
FROM
employee e,
table(e.phone_numbers_col) t
WHERE
emp_id = 1;
Ausgabe¶
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;
Ausgabe¶
PHONE_NUMBERS_COL |
|---|
[ 1234567890 ] |
Zugehörige EWIs¶
[SSC-EWI-0056](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0056): Typ erstellen wird nicht unterstützt.
SSC-EWI-0062: Die Verwendung des CUSTOM-Typs wurde in ‚variant‘ geändert.
[SSC-EWI-0073](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
SSC-EWI-OR0035: Die Tabellenfunktion wird nicht unterstützt, wenn sie als Sammlung von Ausdrücken verwendet wird.
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-FDM-0015: Referenzierter kundenspezifischer Typ in der Abfrage nicht gefunden.
SSC-FDM-OR0035: DBMS_OUTPUT. UDF-Implementierung von PUTLINE-Prüfung.
LOCK TABLE¶
Bemerkung
Nicht relevante Anweisung.
Warnung
Beachten Sie, dass diese Anweisung aus der Migration entfernt wurde, da es sich um eine nicht relevante Syntax handelt. Das bedeutet, dass sie in Snowflake nicht erforderlich ist.
Beschreibung¶
In Oracle ermöglicht die Anweisung LOCK TABLE den expliziten Erwerb einer gemeinsamen oder exklusiven Tabellensperre für die angegebene Tabelle. Die Sperre der Tabelle hält bis zum Ende der aktuellen Transaktion an. Weitere Informationen finden Sie hier.
Syntax
LOCK TABLE tableName IN { SHARE | EXCLUSIVE } MODE
Beispielhafte Quellcode-Muster¶
Tabelle sperren¶
Beachten Sie, dass in diesem Beispiel die Anweisung LOCK TABLE gelöscht wurde. Das liegt daran, dass Snowflake Sperren auf eine andere Art und Weise durch Transaktionen handhabt.
Oracle¶
LOCK TABLE table1 IN EXCLUSIVE MODE;
Snowflake¶
[Empty output]
LOG ERROR¶
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Die Anweisung
FORALLführt eine Anweisung DML mehrfach aus, mit unterschiedlichen Werten in denVALUES- undWHERE-Klauseln. (Oracle PL/SQL Language Reference FORALL Statement).
Oracle-Syntax¶
FORALL index IN bounds_clause [ SAVE ] [ EXCEPTIONS ] dml_statement ;
Warnung
Snowflake Scripting ist nicht direkt gleichwertig mit der Anweisung FORALL, kann aber mit verschiedenen Umgehungsmöglichkeiten emuliert werden, um eine funktionale Gleichwertigkeit zu erreichen.
Beispielhafte Quellcode-Muster¶
Datenkonfiguration¶
Oracle¶
Tabellen¶
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¶
Tabellen¶
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¶
Hinweis
Die drei folgenden Fälle haben die gleiche Transformation zu Snowflake Scripting und sind funktional gleichwertig.
Fall 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 mit Sammlung von Datensätzen¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
Mit 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;
Mit 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;
Ergebnisse von INSERT INTO¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
1 |
2 |
Ergebnisse von UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
Snowflake¶
Mit 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;
$$;
Mit 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;
$$;
Ergebnisse von 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 |
Ergebnisse von UPDATE¶
COLUMN1 |
COLUMN2 |
|---|---|
1.000000000000000000 |
2.000000000000000000 |
4. FORALL With Record of Collections¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent in 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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
1 |
2 |
1 |
2 |
2 |
3 |
3 |
4 |
4 |
5 |
5 |
6 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
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¶
FORALL-Beispiel¶
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;
Ergebnisse¶
COLUMN1 |
COLUMN2 |
|---|---|
54321 |
2 |
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
ambiguous column name 'COLUMN2'
8. FORALL With DELETE Statements¶
Oracle¶
FORALL-Beispiel¶
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;
Ergebnisse¶
no data found
Snowflake¶
FORALL-Äquivalent¶
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;
$$;
Ergebnisse¶
Query produced no results
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
SSC-EWI-0030: Die folgende Anweisung enthält Verwendungen von dynamischem SQL.
[SSC-EWI-0036](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0036): Datentyp in einen anderen Datentyp konvertiert.
SSC-EWI-0058: Die Funktionalität wird derzeit nicht von Snowflake Scripting unterstützt.
SSC-EWI-0062: Die Verwendung des CUSTOM-Typs wurde in ‚variant‘ geändert.
SSC-EWI-OR0129: Das TYPE-Attribut konnte nicht aufgelöst werden.
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-FDM-OR0031: Die Klausel zur Fehlerprotokollierung in DML-Anweisungen wird von Snowflake nicht unterstützt.
SSC-PRF-0001: Diese Anweisung umfasst die Verwendung von Cursor-Fetch-Bulk-Vorgängen.
SSC-PRF-0003: Das Abrufen innerhalb einer Schleife wird als komplexes Muster betrachtet; dies kann die Leistung von Snowflake beeinträchtigen.
LOOP¶
Übersetzungsreferenz zur Konvertierung der LOOP-Anweisung von Oracle in Snowflake Scripting
Beschreibung¶
Mit jeder Iteration der BASIC
LOOP-Anweisung werden die zugehörigen Anweisungen ausgeführt und die Kontrolle kehrt zum Anfang der Schleife zurück. DieLOOP-Anweisung endet, wenn eine Anweisung innerhalb der Schleife die Kontrolle an außerhalb der Schleife überträgt oder eine Ausnahme auslöst.\ (Oracle PL/SQL-Sprachreferenz – BASIC LOOP-Anweisung)
BASIC LOOP-Syntax von Oracle¶
LOOP statement... END LOOP [ label ] ;
BASIC LOOP-Syntax von Snowflake Scripting¶
LOOP
<statement>;
[ <statement>; ... ]
END LOOP [ <label> ] ;
Die Verhaltensweise von Oracle BASIC LOOP kann auch durch die Verwendung der Anweisungen geändert werden:
Beispielhafte Quellcode-Muster¶
Simple Loop-Case¶
Hinweis
Dieser Fall ist funktionell gleichwertig.
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
Keine zugehörigen EWIs.
OUTPUT PARAMETERS¶
Beschreibung¶
Ein Ausgabeparameter ist ein Parameter, dessen Wert aus der gespeicherten Prozedur/dem Funktionsmodul zurück an den aufrufenden PL/SQL-Block übergeben wird. Da die Ausgabeparameter von Snowflake Scripting nicht unterstützt werden, wurde eine Lösung implementiert, um ihre Funktionalität zu emulieren.
Beispielhafte Quellcode-Muster¶
Einzelner Out-Parameter¶
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;
Snowflake Scripting¶
-- 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;
$$;
Mehrere Out-Parameter¶
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;
Snowflake Scripting¶
-- 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;
$$;
Um zu überprüfen, ob die Funktionalität korrekt emuliert wird, führt die folgende Abfrage die Prozedur und SELECT aus der zuvor erwähnten Tabelle aus.
Oracle¶
CALL proc_with_single_output_parameters();
CALL proc_with_multiple_output_parameters();
SELECT * FROM table01;
Ergebnis¶
COL1 |
COL2 |
|---|---|
123 |
-1 |
123 |
456 |
Snowflake Scripting¶
CALL proc_with_single_output_parameters();
CALL proc_with_multiple_output_parameters();
SELECT * FROM table01;
Ergebnis¶
COL1 |
COL2 |
|---|---|
123.000000000000000000 |
-1 |
123.000000000000000000 |
456.000000000000000000 |
Kundendatentyp OUT-Parameter¶
Wenn der Ausgabeparameter ein Kundendatentyp ist, ähnelt der Prozess einem regulären Datentyp.
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;
Snowflake Scripting¶
--** 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;
$$;
Cursor OUT-Parameter¶
Cursor OUT-Parameter werden in Snowflake nicht unterstützt; dennoch wird eine Problemumgehung, die das Verhalten von Oracle emuliert, auf den transformierten Code angewendet. Die Prozedur mit den OUT-Parametern erzeugt eine temporäre Tabelle mit einem dynamischen Namen, und der Prozeduraufruf definiert den Namen der temporären Tabelle als Zeichenfolge, um die Tabelle innerhalb des Prozeduraufrufs zu erstellen.
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;
/
Snowflake Scripting¶
--** 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;
$$;
Datensatz OUT-Parameter¶
Datensätze werden in Snowflake nicht nativ unterstützt; es wurde jedoch eine Problemumgehung verwendet, um sie als Ausgabeparameter zu emulieren. Durch die Definition einer OBJECT-Variablen anstelle des Datensatzes können wir die Feldstruktur des Datensatzes emulieren, indem wir das Ergebnis des Out-Parameters jeder Objekteigenschaft zuweisen. Außerdem wird für jedes Datensatzfeld, das als Ausgabeparameter zugewiesen ist, eine neue Variable mit dem Feldtyp generiert.
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;
Snowflake Scripting¶
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;
$$;
Paketvariablen als OUT-Parameter¶
Pakete werden in Snowflake nicht unterstützt, daher sollten deren lokale Members, wie Variablen oder Konstanten, ebenfalls mithilfe einer Problemumgehung erhalten werden. In diesem Szenario würde die Paketvariable mithilfe einer Sitzungsvariablen emuliert, die nach dem Festlegen einer lokalen Variablen mit dem Ausgabeparameterergebnis aktualisiert würde.
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;
Snowflake Scripting¶
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;
$$;
Bekannte Probleme¶
1. Procedures with output parameters inside packages may not work correctly¶
Derzeit gibt es ein Problem bei der Erfassung der semantischen Informationen von Prozeduren, die sich innerhalb von Paketen befinden. Aus diesem Grund kann die Transformation für Ausgabeparameter nur teilweise oder gar nicht funktionieren. Es wird bereits daran gearbeitet, dieses Problem zu lösen.
2. Some data types may not work properly¶
Wie in der Transformation zu sehen ist, wird beim Abrufen des Wertes aus den aufgerufenen Prozeduren eine implizite Transformation von VARIANT auf den von der Variablen angegebenen Typ durchgeführt. Da es viele mögliche Datentypen gibt, können einige Übertragungen fehlschlagen oder andere Daten enthalten.
Zugehörige EWIs¶
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-FDM-0007: Element mit fehlenden Abhängigkeiten.
SSC-FDM-0015: Datentyp wird nicht erkannt.
NESTED-PROCEDURES¶
Beschreibung¶
In PL/SQL von Oracle bezieht sich NESTED PROCEDURES auf eine Prozedur, die innerhalb des deklarativen Abschnitts eines anderen PL/SQL-Blocks deklariert und definiert wird. Dieser übergeordnete Block kann eine andere Prozedur, eine Funktion oder ein Pakettext sein. Weitere Informationen finden Sie in der Dokumentation zu Oracle-Prozedurdeklarationen und -Definitionen.
Bemerkung
Die im Folgenden beschriebenen Transformationen sind spezifisch für Prozeduren, die in andere Prozeduren oder Pakete eingebettet sind.
Beispielhafte Quellcode-Muster¶
Modus für IN-Parameter für verschachtelte Prozeduren¶
Das IN-Schlüsselwort wird entfernt, da verschachtelte Snowflake-Prozeduren IN-Parameter nur implizit unterstützen.
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;
Snowflake Scripting¶
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;
$$;
Modus für OUT-Parameter für verschachtelte Prozeduren¶
Die verschachtelten Prozeduren von SnowScript unterstützen keine Ausgabeparameter. Um diese Funktionalität in Snowflake zu replizieren, muss ein RETURN-Typ auf der Grundlage der Ausgabeparameter erstellt werden.
Wenn es nur einen Ausgabeparameter gibt, wird dieser Parameter am Ende zurückgegeben. Bei mehreren Ausgabeparametern wird ein Objektkonstrukt generiert, das deren Werte enthält. Während des Aufrufs werden diese Werte einer Variablen zugewiesen und anschließend werden diese Ergebnisse den entsprechenden Variablen oder Parametern zugewiesen.
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;
Snowflake Scripting¶
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;
$$;
Mehrere OUT Parameter in verschachtelten Prozeduren¶
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;
Snowflake Scripting¶
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;
$$;
Verschachtelte Prozeduren auf mehreren Ebenen¶
Snowflake erlaubt nur eine Verschachtelungsebene für verschachtelte Prozeduren. Daher wird eine verschachtelte Prozedur innerhalb einer anderen verschachtelten Prozedur nicht unterstützt. Tritt ein solcher Fall auf, enthält die Transformation den Fehler !!!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;
Snowflake Scripting¶
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;
$$;
Standardwerte in verschachtelten Prozeduren¶
Argumente in verschachtelten Prozeduren unterstützen keine Standardklauseln. Wenn also ein verschachtelter Prozeduraufruf einen optionalen Parameter weglässt, muss der Standardwert für dieses Argument innerhalb des Prozeduraufrufs übergeben werden. SnowConvert AI identifiziert diese Szenarios automatisch und füllt die Prozeduraufrufe entsprechend.
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;
Snowflake Scripting¶
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;
$$;
Überladen von verschachtelten Prozeduren¶
Snowflake unterstützt nicht das Überladen von verschachtelten Prozeduren. Tritt ein solcher Fall auf, wird der EWI SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED hinzugefügt.
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;
Snowflake Scripting¶
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;
$$;
Verschachtelte Prozedur ohne Parameterliste¶
In Snowflake erfordert eine verschachtelte Prozedurdefinition leere Klammern (), um syntaktisch gültig zu sein, wenn es keine Parameter hat; im Gegensatz zu Oracle, wo sie nicht benötigt werden. SnowConvert AI fügt diese automatisch während der Übersetzung hinzu.
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;
Snowflake Scripting¶
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;
$$;
Verschachtelte Prozedur mit REFCURSOR-Ausgabeparameter¶
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;
Snowflake Scripting¶
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;
$$;
Verschachtelte Prozedur mit NOCOPY-Parameteroption¶
In Oracle PL/SQL ist das NOCOPY-Schlüsselwort ein Optimierungshinweis für die OUT- und IN OUT-Prozedurparameter. Standardmäßig übergibt Oracle diese Parameter als Wert, erstellt während des Aufrufs eine teure Kopie der Daten und kopiert diese nach Abschluss wieder zurück. Dies kann bei großen Datenstrukturen einen erheblichen Leistungsaufwand verursachen.
NOCOPY weist Oracle an, stattdessen per Referenz zu übergeben, sodass die Prozedur die ursprünglichen Daten direkt ändern kann. Dies reduziert den Kopieraufwand und verbessert die Leistung. Änderungen sind jedoch sofort wirksam und werden nicht implizit rückgängig gemacht, wenn innerhalb der Prozedur eine unberücksichtigte Ausnahme auftritt.
Deshalb entfernen wir die NOCOPY-Parameteroption und fügen FDM SSC-FDM-OR0050 - EXCEPTIONS WITH NOCOPY PARAMETERS MAY LEAD TO DATA INCONSISTENCY hinzu. Dies liegt daran, dass die Ausführung der Prozedur beim Auftreten einer Ausnahme beendet wird und dadurch die RETURN-Anweisung nicht mehr erreicht wird. Infolgedessen behält die Variable im Declare-Block des Aufrufers ihre Anfangswerte bei, da die Prozedur keinen neuen Wert zur Zuweisung erfolgreich zurückliefert.
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;
Snowflake Scripting¶
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;
$$;
Bekannte Probleme¶
1. Multi-level Nested Procedures¶
Unsere Transformationsbemühungen für verschachtelte Prozeduren in Snowflake beschränken sich auf solche, die direkt innerhalb anderer Prozeduren verschachtelt sind und nur eine Ebene der Verschachtelung unterstützen. Wenn es mehr als eine Verschachtelungsebene gibt oder eine Prozedur in einer eigenständigen Funktion verschachtelt ist, wird die Transformation nicht unterstützt und der EWI !!!RESOLVE EWI!!! /*** SSC-EWI-0111 - ONLY ONE LEVEL OF NESTING IS ALLOWED FOR NESTED PROCEDURES IN SNOWFLAKE. ***/!!! wird hinzugefügt.
2. Nested procedures overloading¶
Außerdem wird das Überladen von verschachtelten Prozeduren in Snowflake nicht unterstützt. In solchen Fällen wird der EWI !!!RESOLVE EWI!!! /*** SSC-EWI-0112 - NESTED PROCEDURE OVERLOADING IS NOT SUPPORTED. ***/!!! hinzugefügt.
3. Nested procedures within anonymous blocks¶
Die Transformation für verschachtelte Prozeduren innerhalb anonymer Blöcke ist derzeit ausstehend. Der EWI !!!RESOLVE EWI!!! /*** SSC-EWI-OR0057 - TRANSFORMATION FOR NESTED PROCEDURE OR FUNCTION IS NOT SUPPORTED IN THIS SCENARIO ***/!!! wird hinzugefügt.
Zugehörige EWIs¶
SSC-FDM-OR0050: Ausnahmen mit
NOCOPY-Parametern können zu Dateninkonsistenzen führen.SSC-EWI-OR0057: Die Transformation von verschachtelten Prozeduren oder Funktionen wird nicht unterstützt.
SSC-EWI-0111: Für verschachtelte Prozeduren in Snowflake ist nur eine Ebene der Verschachtelung erlaubt.
SSC-EWI-0112: Das Überladen von verschachtelten Prozeduren wird nicht unterstützt.
PROCEDURE CALL¶
Übersetzungsreferenz für PROCEDURE CALL, auch bekannt als SUBPROGRAM INVOCATION
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Dieser Abschnitt beschreibt die Syntax für Unterprogrammaufrufe innerhalb von PL-Blöcken, wie Prozeduren oder anonymen Blöcken.
Weitere Informationen zu diesem Thema finden Sie in der Dokumentation zu Unterprogrammen von Oracle: (Oracle PL/SQL Language Reference Subprogram Invocation Statement)
Prozeduraufrufe können nach Snowflake migriert werden, solange es keine optionalen Parameter gibt und ihre Reihenfolge mit den formalen Parametern übereinstimmt. Bitte beachten Sie, dass Prozeduraufrufe in eine CALL-Anweisung umgewandelt werden.
Syntax von Subprogram Invocation von Oracle¶
<subprogram invocation> := subprogram_name [ ( [ parameter [, parameter]... ] ) ]
<parameter> := {
<actual parameter>
| <formal parameter name> => <actual parameter>
}
Snowflake Scripting unterstützt diese Anweisung, wenn auch mit einigen funktionalen Unterschieden.
Syntax von Subprogram Invocation von Snow Scripting¶
<subprogram invocation> := CALL subprogram_name [ ( [ parameter [, parameter]... ] ) ]
<parameter> := {
<actual parameter>
| <formal parameter name> => <actual parameter>
}
Beispielhafte Quellcode-Muster¶
Bemerkung
Betrachten Sie die nächste Tabelle und die Vorgehensweise für die folgenden Beispiele.
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;
$$;
Einfacher Call¶
Oracle¶
CREATE OR REPLACE PROCEDURE simple_calling_procedure
AS
BEGIN
called_procedure(1);
END;
CALL simple_calling_procedure();
SELECT * FROM procedure_call_test_table;
Ergebnis¶
COL1 |
|---|
1 |
Snowflake Scripting¶
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;
Ergebnis¶
COL1 |
|---|
1 |
Aufrufen einer Prozedur mit einem optionalen Parameter¶
Warnung
Dieses Beispiel beinhaltet manuelle Interventionen zur Behebung einiger funktioneller Unterschiede und dient deren Erläuterung. Weitere Informationen zu diesen Unterschieden finden Sie im Abschnitt Bekannte Probleme unten.
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;
Ergebnis¶
COL1 |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Snowflake Scripting¶
-- 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;
Ergebnis¶
COL1 |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Bekannte Probleme¶
1. Calling Subprograms with default values is not supported¶
Snowflake unterstützt nicht die Einstellung von Standardwerten für Parameter. Diese müssen also bei jedem Call eingegeben werden.
2. Named parameters are accepted, but not functionally equivalent¶
Diese Parameter verursachen keine Kompilierungsfehler, wenn sie in Snowflake ausgeführt werden. Bei Aufrufen werden sie jedoch immer noch positionsbezogen platziert. Aus diesem Grund muss die Reihenfolge dieser Parameter überprüft werden. SnowConvert AI unterstützt weder die Überprüfung noch die Neuanordnung dieser Parameter.
3. Calling Subprograms with Out Parameters is not supported¶
Snowflake bietet keine Unterstützung für Parametermodi, aber es wird eine Lösung implementiert, um deren Funktionalität zu emulieren. Weitere Informationen über die Transformation von Ausgabeparametern finden Sie im folgenden Artikel Ausgabeparameter.
Zugehörige EWIs¶
SSC-EWI-0002: Standardparameter müssen möglicherweise neu angeordnet werden.
SSC-FDM-0007: Element mit fehlenden Abhängigkeiten.
RAISE¶
Beschreibung¶
Die Anweisung
RAISElöst ausdrücklich eine Ausnahme aus.Außerhalb eines Ausnahme-Handlers müssen Sie den Namen der Ausnahme angeben. Wenn Sie innerhalb eines Ausnahme-Handlers den Ausnahme-Namen weglassen, löst die Anweisung
RAISEdie aktuelle Ausnahme erneut aus. (Oracle PL/SQL Language Reference Raise Statement)
Die Anweisung wird von Snowflake Scripting vollständig unterstützt, aber bitte beachten Sie, dass es bei einigen COMMIT- und ROLLBACK-Anweisungen zu Unterschieden kommen kann.
RAISE <exception_name> ;
Snowflake Scripting bietet Unterstützung für diese Anweisung.
RAISE <exception_name> ;
Beispielhafte Quellcode-Muster¶
Einfache Ausnahme auslösen¶
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);
Ergebnis¶
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.
Snowflake Scripting¶
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);
Ergebnis¶
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
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
Keine zugehörigen EWIs.
RAISE_APPICATION_ERROR¶
Übersetzungsreferenz für die raise_application_error-Anweisung.
Allgemeine Beschreibung¶
Mit der Prozedur RAISE_APPLICATION_ERROR können Sie benutzerdefinierte ORA- Fehlermeldungen aus gespeicherten Unterprogrammen ausgeben. Auf diese Weise können Sie Fehler an Ihre Anwendung melden und vermeiden, dass unbehandelte Ausnahmen zurückgegeben werden (Oracle-Dokumentation).
Oracle-Syntax¶
raise_application_error(
error_number, message[, {TRUE | FALSE}]);
Bemerkung
Die error_number ist eine negative Ganzzahl im Bereich -20000 … -20999 und message ist eine Zeichenfolge mit einer Länge von bis zu 2048 Bytes.
Wenn der optionale dritte Parameter TRUE lautet, wird der Fehler auf dem Stapel der vorherigen Fehler abgelegt. Wenn der Parameter FALSE lautet (die Vorgabe), ersetzt der Fehler alle vorherigen Fehler.
Die entsprechende Anweisung in Snowflake ist die RAISE-Klausel. Dennoch ist es erforderlich, die benutzerdefinierte Ausnahme als Variable zu deklarieren, bevor Sie die RAISE-Anweisung dafür aufrufen.
Snowflake-Syntax¶
<exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
Bemerkung
Weitere Informationen finden Sie in der folgenden Snowflake-Dokumentation.
Beispielhafte Quellcode-Muster¶
1. Exception in functions without declaring section¶
In diesem Szenario wird die Funktion ohne einen deklarierenden Abschnitt in eine Prozedur mit der Ausnahmedeklaration übersetzt. Bitte beachten Sie das:
Der Name der Ausnahmevariablen wird in Großbuchstaben angegeben.
Der Name der Ausnahmevariable basiert auf der Beschreibung und eine Endung besteht aus einem Ausnahmecodenamen gefolgt von einer fortlaufenden Nummer.
Der Deklarationsabschnitt wird erstellt, auch wenn die ursprüngliche Funktion oder Prozedur ihn nicht enthält.
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;
Ausgabe¶
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;
$$;
Ausgabe¶
FIRST EXCEPTION MESSAGE
2. Exception code number outside limits¶
Im folgenden Beispiel ist die Übersetzung im Body der Prozedur auskommentiert. Das liegt daran, dass der Code außerhalb der in Snowflake geltenden Grenzwerte liegt. Die Lösung besteht darin, den Ausnahmecode für einen verfügbaren Code im Abschnitt Abfrage zu ändern.
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;
Ausgabe¶
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;
$$;
Ausgabe¶
Invalid error code '-20,000'. Must be between -20,999 and -20,000
3. Exception stack functionality¶
Die Funktionalität des Ausnahmestapels wird in Snowflake nicht unterstützt und wurde aus der Ausnahmedeklaration entfernt.
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;
Ausgabe¶
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;
$$;
Ausgabe¶
MY EXCEPTION MESSAGE
4. Multiple exceptions with the same exception code¶
Mehrere Ausnahmen mit der gleichen können im deklarierenden Abschnitt und in den RAISE-Anweisungen nebeneinander bestehen.
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;
Ausgabe¶
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;
$$;
Ausgabe¶
THE FIRST EXCEPTION
Bekannte Probleme¶
SQLREM-Funktion überprüft werden kann.
Die Ausnahmecode-Nummer außerhalb der geltenden Grenzen in Snowflake muss in eine verfügbare Code-Ausnahme geändert werden.
„Zu einem Fehlerstapel hinzufügen“ wird nicht unterstützt.
Zugehörige EWIs¶
SSC-EWI-OR0099: Der Ausnahmecode überschreitet die Snowflake Scripting-Beschränkung
SSC-FDM-0029: Die benutzerdefinierte Funktion wurde in eine Snowflake-Prozedur umgewandelt.
SSC-FDM-OR0011: Das boolesche Argument wurde entfernt, da die Option „Add to stack“ nicht unterstützt wird.
UDF CALL¶
Übersetzungsreferenz für den Aufruf von benutzerdefinierten Funktionen (UDFs)
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Wie allgemein bekannt, werden nicht-skalare benutzerdefinierte Funktionen (UDFs) in Oracle in gespeicherte Prozeduren von Snowflake umgewandelt, um kompliziertere Funktionalitäten zu ermöglichen.
Diese Transformation ändert auch die Art und Weise, wie die Funktion aufgerufen wird, indem sie von einem traditionellen Funktionsaufruf zu einem Aufruf einer gespeicherten Prozedur übergeht.
Weitere Einzelheiten zum Aufruf von gespeicherten Prozeduren finden Sie in der hier verfügbaren Dokumentation: PROCEDURE CALL.
Beispielhafte Quellcode-Muster¶
Bemerkung
Betrachten Sie die nächste Funktion und die Tabellen für die folgenden Beispiele.
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" }}'
;
UDF-Aufruf¶
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;
Ergebnis¶
ID RESULT_COL
1 8
Snowflake Scripting¶
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;
Ergebnis¶
ID RESULT_COL
1 8
UDF-Aufruf innerhalb einer Abfrage¶
Wenn ein Funktionsaufruf in eine Abfrage eingebettet ist, wird der Aufrufprozess komplizierter, da Snowflake nicht in der Lage ist, Prozeduren direkt in Abfragen aufzurufen. Um diese Beschränkung zu überwinden, wird der Aufruf der Prozedur außerhalb der Abfrage verschoben und das Ergebnis einer Variablen zugewiesen. Diese Variable wird dann in der Abfrage referenziert, wodurch eine Funktionsäquivalenz erreicht wird. Dieser Ansatz ermöglicht die Ausführung komplexerer Verhaltensweisen innerhalb von Snowflake-Abfragen unter Einhaltung der prozeduralen Einschränkungen.
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;
Ergebnis¶
ID RESULT_COL
1 6
2 7
Snowflake Scripting¶
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;
Ergebnis¶
ID RESULT_COL
1 6
2 7
Bekannte Probleme¶
1. Unsupported Usage of UDFs in Queries with Query Dependencies¶
Beim Aufruf von benutzerdefinierten Funktionen (UDFs) innerhalb von Abfragen mit Abfrageabhängigkeiten werden Szenarien mit eingebetteten Funktionen mit Spalten als Argumente nicht unterstützt. Diese Beschränkung ergibt sich, weil auf die Spaltenwerte nicht von außerhalb der Abfrage zugegriffen werden kann. Beispiele für nicht unterstützte Szenarien sind:
BEGIN
SELECT
sum_to_varchar_function(ext.col1, ext.col2) -- columns as arguments not supported
INTO
result_value
FROM example_table ext;
END;
\ Die unterstützten Szenarien umfassen Funktionsaufrufe mit anderen Arten von Argumenten, wie z. B. Literalwerte, externe Variablen oder Parameter. Zum Beispiel:
BEGIN
SELECT
sum_to_varchar_function(100, param1)
INTO
result_value
FROM example_table ext;
END;
In den unterstützten Szenarien kann die Funktion effektiv migriert werden.
Zugehörige EWIs¶
[SSC-EWI-0073](../../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
SSC-FDM-0006: Spalte vom Typ ‚number‘ verhält sich in Snowflake möglicherweise nicht ähnlich.
SSC-FDM-0029: Die benutzerdefinierte Funktion wurde in eine Snowflake-Prozedur umgewandelt.
WHILE¶
Übersetzungsreferenz zur Konvertierung der WHILE-Anweisung von Oracle in Snowflake Scripting
Beschreibung¶
Die
WHILELOOP-Anweisung führt eine oder mehrere Anweisungen aus, während eine BedingungTRUElautet.\ (Oracle PL/SQL-Sprachreferenz – WHILE-Anweisung)
Syntax der WHILE-Anweisung von Oracle¶
WHILE boolean_expression
LOOP statement... END LOOP [ label ] ;
Syntax der WHILE-Anweisung von Snowflake Scripting¶
WHILE ( <condition> ) { DO | LOOP }
<statement>;
[ <statement>; ... ]
END { WHILE | LOOP } [ <label> ] ;
Die Verhaltensweise von Oracle WHILE kann auch durch die Verwendung der Anweisungen geändert werden:
Beispielhafte Quellcode-Muster¶
Simple While-Case¶
Hinweis
Dieser Fall ist funktionell gleichwertig.
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Snowflake Scripting¶
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;
Ergebnis¶
ITERATOR |
|---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
Keine zugehörigen EWIs.