Some parts in the output code are omitted for clarity reasons.
A stored function (also called a user function or user-defined function) is a set of PL/SQL statements you can call by name. Stored functions are very similar to procedures, except that a function returns a value to the environment in which it is called. User functions can be used as part of a SQL expression.
A call specification declares a Java method or a third-generation language (3GL) routine so that it can be called from PL/SQL. You can also use the CALL SQL statement to call such a method or routine. The call specification tells Oracle Database which Java method, or which named function in which shared library, to invoke when a call is made. It also tells the database what type conversions to make for the arguments and return value. Oracle SQL Language Reference Create Function.
SQL user-defined functions only support one query as their body. They can read from the database but are not allowed to write to or modify it (Scalar SQL UDFs).
CREATE[ORREPLACE][SECURE]FUNCTION<name>([<arg_name><arg_data_type>][,...])RETURNS{<result_data_type>|TABLE(<col_name><col_data_type>[,...])}[[NOT]NULL][{ CALLED ONNULLINPUT|{RETURNSNULLONNULLINPUT|STRICT}}][VOLATILE|IMMUTABLE][COMMENT='<string_literal>']AS'<function_definition>'
JavaScript user-defined functions allow multiple statements in their bodies but cannot perform queries to the database. (Scalar JavaScript UDFs).
CREATE[ORREPLACE][SECURE]FUNCTION<name>([<arg_name><arg_data_type>][,...])RETURNS{<result_data_type>|TABLE(<col_name><col_data_type>[,...])}[[NOT]NULL]LANGUAGEJAVASCRIPT[{ CALLED ONNULLINPUT|{RETURNSNULLONNULLINPUT|STRICT}}][VOLATILE|IMMUTABLE][COMMENT='<string_literal>']AS'<function_definition>'
Some parts in the output code are omitted for clarity reasons.
This pattern defines a function in Oracle PL/SQL that uses a cursor to fetch a single value and return it.
Components:
Function Declaration:
CREATE FUNCTION functionName(parameters) RETURN returnType
Declares the function with input parameters and the return type.
Variable Declarations:
Declares variables, including the return variable.
Cursor Declaration:
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];
Defines a cursor to select a single column from a table with optional filtering conditions.
BEGIN-END Block:
Variables assignment.
Opens the cursor.
Fetch the result into the return variable.
Closes the cursor.
Returns the fetched value.
In this case, the variables are transformed into a common table expression (CTE). As well as the query within the cursor to which, in addition, the FETCH FIRST 1 ROW ONLY clause is added to simulate the FETCH CURSOR behavior.
RETURN statement is transformed to the final select.
CREATEORREPLACEFUNCTION func1 (company_ VARCHAR, book_id_ TIMESTAMP/*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/, object_id_ VARCHAR)RETURNSINTEGERLANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "09/06/2024" }}'AS$$
WITH declaration_variables_cte1 AS
(
SELECT
(
SELECT col2
FROM table1
WHERE col3 = company_
AND col4 = object_id_
AND col5 = book_id_
FETCH FIRST 1 ROW ONLY) AS temp_
)
SELECT
temp_
FROM
declaration_variables_cte1
$$;
CREATEORREPLACEFUNCTION func2 (fa_period_ NUMBER(38,18),
to_date_ TIMESTAMP/*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/DEFAULTNULL,
from_date_ TIMESTAMP/*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/DEFAULTNULL)RETURNSNUMBER(38,18)LANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "09/06/2024" }}'AS$$
WITH declaration_variables_cte1 AS
(
SELECT
0 AS
value_,
Get_Cond_Date( to_date_, 'MAX' ) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Get_Cond_Date' NODE ***/!!! AS
cond_date_to_,
Get_Cond_Date( from_date_, 'MIN' ) !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Get_Cond_Date' NODE ***/!!! AS
cond_date_from_
),
declaration_variables_cte2 AS
(
SELECT
(
SELECT NVL(SUM(col1),0)
FROM table1
WHERE col3 IN (DECODE(fa_period_, 1, 'val1_1', 'val2_1'))
AND col5 <= cond_date_to_
AND col5 >= cond_date_from_
FETCH FIRST 1 ROW ONLY) AS value_,
cond_date_to_,
cond_date_from_
FROM
declaration_variables_cte1
)
SELECT
(NVL(value_,0))
FROM
declaration_variables_cte2
$$;
Some parts in the output code are omitted for clarity reasons.
This pattern defines a function that conditionally uses a cursor to fetch and return a value based on an IF statement.
Components:
Function Declaration:
CREATE FUNCTION functionName(parameters) RETURN returnType
Declares the function with input parameters and the return type.
Cursor Declaration:
CURSOR cursorName IS SELECT singleColumn FROM ... WHERE ... [AND col1 = localVar1];
Defines a cursor to select a single column from a table with optional filtering conditions.
Variable Declaration:
Declares variables, including the return variable.
BEGIN-END Block with IF Statement:
Variables assignment.
Check if a condition is true.
If true, opens the cursor, fetches the result into the return variable, closes the cursor, and returns the fetched value. (The cursor can also be opened in the ELSE block and must meet the same conditions)
The ELSE Block is optional, if it exists, it should only contain a single statement that can be an assignment or a RETURN statement.
The variables are transformed into a common table expression (CTE). As well as the query within the cursor to which, in addition, the FETCH FIRST 1 ROW ONLY clause is added to simulate the FETCH CURSOR behavior.
IF/ELSE statement can be handled using the CASE EXPRESSION inside the select allowing conditionals inside the queries. RETURN statement is transformed to the final select..
CREATEORREPLACEFUNCTION func2 (company_ NUMBER(38,18))RETURNSNUMBER(38,18)LANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "09/06/2024" }}'AS$$
WITH declaration_variables_cte0 AS
(
SELECT
1 AS
max_period_
),
declaration_variables_cte1 AS
(
SELECT
2 AS
max_period_
FROM
declaration_variables_cte0
),
declaration_variables_cte2 AS
(
SELECT
CASE
WHEN company_ = 1
THEN max_period_ * 2
ELSE (
SELECT max(col2)
FROM table1
FETCH FIRST 1 ROW ONLY)
END AS max_period_
FROM
declaration_variables_cte1
)
SELECT
max_period_
FROM
declaration_variables_cte2
$$;
CREATEORREPLACEFUNCTION Case1 (in_date_ TIMESTAMP/*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/, min_max_ VARCHAR)RETURNSTIMESTAMP/*** SSC-FDM-OR0042 - DATE TYPE COLUMN HAS A DIFFERENT BEHAVIOR IN SNOWFLAKE. ***/LANGUAGESQLCOMMENT='{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "oracle", "convertedOn": "09/06/2024" }}'AS$$
WITH declaration_variables_cte0 AS
(
SELECT
CURRENT_DATE AS
cond_date_
),
declaration_variables_cte1 AS
(
SELECT
CASE
WHEN ( in_date_ IS NULL )
THEN CASE
WHEN ( min_max_ = 'MIN' )
THEN FOO1() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO1' NODE ***/!!!
ELSE FOO2() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'FOO2' NODE ***/!!!
END
ELSE TRUNC(in_date_, 'DD')
END AS cond_date_
FROM
declaration_variables_cte0
)
SELECT
cond_date_
FROM
declaration_variables_cte1
$$;
SnowConvert now supports translating Oracle PL/SQL User Defined Functions directly to Snowflake Scripting UDFs (SnowScript UDFs) when they meet specific criteria.
Snowflake Scripting UDFs are user-defined functions written using Snowflake’s procedural language syntax (Snowscript) within a SQL UDF body. They support variables, loops, conditional logic, and exception handling without requiring database access.
SnowConvert analyzes each Oracle function and automatically determines the appropriate Snowflake target. A function becomes a SnowScript UDF when it contains only procedural logic without data access operations.
SnowConvert AI will not translate UDFs containing the following elements into SnowScripting UDFs, as these features are unsupported in SnowScripting UDFs: