📘 Translation ReferencesTeradata SQL to Snowflake Scripting (Procedures) CREATE PROCEDURE Translation reference to convert Teradata CREATE PROCEDURE to Snowflake Scripting
Description
The Teradata CREATE PROCEDURE
and REPLACE PROCEDURE
statement generates or replaces a stored procedure implementation and compiles it.
For more information about CREATE PROCEDURE
or REPLACE PROCEDURE
click here .
Copy -- Create/replace procedure syntax
{ CREATE | REPLACE } PROCEDURE [database_name. | user_name.] procedure_name
([<parameter_definition>[, ...n]])
[<SQL_data_access>]
[DYNAMIC RESULT SETS number_of_sets]
[SQL SECURITY <privilege_option>]
statement ;
< parameter_definition > : = [IN | OUT | INOUT] parameter_name data_type
< SQL_data_access > : = {CONTAINS SQL | MODIFIES SQL DATA | READS SQL DATA }
< privilege_option > : = {CREATOR | DEFINER | INVOKER | OWNER }
Sample Source Patterns
Setup data
The following code is necessary to execute the sample patterns present in this section.
Teradata Snowflake
Copy CREATE TABLE inventory (
product_name VARCHAR ( 50 ),
price INTEGER
);
INSERT INTO inventory VALUES ( 'Bread' , 50 );
INSERT INTO inventory VALUES ( 'Tuna' , 150 );
INSERT INTO inventory VALUES ( 'Gum' , 20 );
INSERT INTO inventory VALUES ( 'Milk' , 80 );
Copy CREATE OR REPLACE TABLE inventory (
product_name VARCHAR ( 50 ),
price INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
INSERT INTO inventory
VALUES ( 'Bread' , 50 );
INSERT INTO inventory
VALUES ( 'Tuna' , 150 );
INSERT INTO inventory
VALUES ( 'Gum' , 20 );
INSERT INTO inventory
VALUES ( 'Milk' , 80 );
Basic Procedure
Teradata
Query Result
Copy REPLACE PROCEDURE BasicProcedure( IN counterValue INTEGER )
BEGIN
DECLARE productName VARCHAR ( 50 );
DECLARE productPrice INTEGER DEFAULT 0 ;
DECLARE whileCounter INTEGER DEFAULT 0 ;
SET productName = 'Salt' ;
WHILE (whileCounter < counterValue) DO
SET productPrice = 10 + productPrice;
SET whileCounter = whileCounter + 1 ;
END WHILE ;
INSERT INTO inventory VALUES (productName, productPrice);
END ;
CALL BasicProcedure( 5 );
SELECT product_name, price FROM inventory WHERE product_name = 'Salt' ;
Copy +--------------+--------------+
| product_name | price |
|--------------+--------------|
| Salt | 50 |
+--------------+--------------+
Snowflake Scripting
Query Result
Copy CREATE OR REPLACE PROCEDURE BasicProcedure (COUNTERVALUE INTEGER )
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
productName VARCHAR ( 50 );
productPrice INTEGER DEFAULT 0 ;
whileCounter INTEGER DEFAULT 0 ;
BEGIN
productName : = 'Salt' ;
WHILE (whileCounter < counterValue) LOOP
productPrice : = 10 + productPrice;
whileCounter : = whileCounter + 1 ;
END LOOP ;
INSERT INTO inventory
VALUES (:productName, :productPrice);
END ;
$$;
CALL BasicProcedure( 5 );
SELECT
product_name,
price FROM
inventory
WHERE product_name = 'Salt' ;
Copy +--------------+--------------+
| product_name | price |
|--------------+--------------|
| Salt | 50 |
+--------------+--------------+
Single out parameter
Teradata
Query Result
Copy REPLACE PROCEDURE procedureLabelSingle( OUT Message VARCHAR ( 100 ))
BEGIN
set Message = 'Assignment value. Thanks' ;
END ;
CALL procedureLabelSingle(?);
Copy Message |
------------------------+
Assignment value. Thanks|
Snowflake Scripting
Query Result
Copy CREATE OR REPLACE PROCEDURE procedureLabelSingle (
-- OUT
MESSAGE VARCHAR ( 100 ))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
Message : = 'Assignment value. Thanks' ;
RETURN Message ;
END ;
$$;
CALL procedureLabelSingle(?);
Copy +───────────────────────────────+
| PROCEDURELABELSINGLE |
+───────────────────────────────+
| ""Assignment value. Thanks"" |
+───────────────────────────────+
Multiple out parameter
Teradata
Query Result
Copy REPLACE PROCEDURE procedureLabelMultiple( OUT Message VARCHAR ( 100 ), OUT Message2 VARCHAR ( 100 ))
BEGIN
set Message = 'Assignment value. Thanks' ;
set Message2 = 'Assignment value2. Thanks' ;
END ;
CALL procedureLabelSingle(?, ?);
Copy 1 |2 |
------------------------+-------------------------+
Assignment value. Thanks|Assignment value2. Thanks|
Snowflake Scripting
Query Result
Copy CREATE OR REPLACE PROCEDURE procedureLabelMultiple (
-- OUT
MESSAGE VARCHAR ( 100 ),
-- OUT
MESSAGE2 VARCHAR ( 100 ))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
Message : = 'Assignment value. Thanks' ;
Message2 : = 'Assignment value2. Thanks' ;
RETURN OBJECT_CONSTRUCT( 'Message' , : Message , 'Message2' , :Message2);
END ;
$$;
CALL procedureLabelSingle(?, ?);
Copy +─────────────────────────+────────────────────────────────+
| PROCEDURELABELMULTIPLE | |
+─────────────────────────+────────────────────────────────+
| "{ | |
| ""Message"" | ""Assignment value. Thanks"", |
| ""Message2"" | ""Assignment value2. Thanks"" |
| }" | |
+─────────────────────────+────────────────────────────────+
Inside a procedure, the returned object can be easily deconstructed by using the following statements right after performing the procedure call:
LET call_results VARIANT := (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())));
var1 := GET(:call_results, 'Message');
var2 := GET(:call_results, 'Message2');
\
Multiple out parameter with dynamic result sets
Teradata
Query Result
Copy REPLACE PROCEDURE Procedure1( out product_name VARCHAR ( 50 ), out price integer )
DYNAMIC RESULT SETS 2
BEGIN
DECLARE result_set CURSOR WITH RETURN ONLY FOR
SELECT * FROM inventory;
DECLARE result_set2 CURSOR WITH RETURN ONLY FOR
SELECT * FROM inventory;
SET price = 100 ;
SET product_name = 'another2' ;
OPEN result_set2;
OPEN result_set;
END ;
REPLACE PROCEDURE Procedure2()
BEGIN
DECLARE price INTEGER ;
DECLARE productName varchar ( 10 );
CALL Procedure1(productName, price);
INSERT INTO inventory VALUES (:productName, :price);
END ;
CALL Procedure2();
Snowflake Scripting
Query Result
Copy CREATE OR REPLACE PROCEDURE Procedure1 ( out !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'OUTPUT PARAMETERS ALONG WITH DYNAMIC RESULT SET' NODE ***/ !!! PRODUCT_NAME VARCHAR ( 50 ), out !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'OUTPUT PARAMETERS ALONG WITH DYNAMIC RESULT SET' NODE ***/ !!! PRICE integer )
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
tbl_result_set VARCHAR ;
tbl_result_set2 VARCHAR ;
return_arr ARRAY : = array_construct();
BEGIN
tbl_result_set : = 'RESULTSET_' || REPLACE ( UPPER (UUID_STRING()), '-' , '_' );
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set) AS
SELECT
* FROM
inventory;
LET result_set CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
tbl_result_set2 : = 'RESULTSET_' || REPLACE ( UPPER (UUID_STRING()), '-' , '_' );
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set2) AS
SELECT
* FROM
inventory;
LET result_set2 CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
price : = 100 ;
product_name : = 'another2' ;
OPEN result_set2 USING (tbl_result_set2);
return_arr : = array_append(return_arr, :tbl_result_set2);
OPEN result_set USING (tbl_result_set);
return_arr : = array_append(return_arr, :tbl_result_set);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN OBJECT_CONSTRUCT( 'SC_RET_VALUE' , :return_arr, 'product_name' , :product_name, 'price' , :price);
END ;
$$;
CREATE OR REPLACE PROCEDURE Procedure2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
price INTEGER ;
productName varchar ( 10 );
call_results VARIANT;
BEGIN
call_results : = (
CALL Procedure1(:productName, :price)
);
productName : = :call_results:product_name;
price : = :call_results:price;
INSERT INTO inventory
VALUES (:productName, :price);
END ;
$$;
CALL Procedure2();
Known Issues
1. Out Parameters
Snowflake Scripting does not support OUT/INOUT parameters therefore these parameters are returned at the end of the procedure's body.
2. SQL Data Access
By default, Snowflake procedures support the execution of any kind of SQL statements, including data reading or modification statements, making the SQL data access clause non-relevant. This clause will be ignored when converting the procedure.
3. Top Level Objects in Assessment Report
Elements (Temporal tables or Views) inside Stored Procedures are being counted in the Assessment report as Top Level Objects. The SnowConvert team is now working on a fix for this scenario.
Related EWIs
SSC-FDM-0020 : Multiple result sets are returned in temporary tables.
Last updated 4 months ago