Stored procedures, packages, functions, and triggers parsed structurally. Converted to Snowflake Scripting and Snowpark Python. 2,000+ built-in function mappings, full lineage, validated parity.
Upload PL/SQL, get converted code →Snowflake Scripting supports variables, loops, cursors, and exception handling -- the closest procedural match to PL/SQL of any cloud platform. MigryX maps Oracle's procedural blocks directly to Snowflake's DECLARE / BEGIN / EXCEPTION structure with minimal structural change.
Oracle's proprietary START WITH...CONNECT BY PRIOR syntax has a clean equivalent in Snowflake's recursive CTE support. MigryX preserves hierarchical semantics including LEVEL pseudo-column, SYS_CONNECT_BY_PATH, and cycle detection.
NVL, DECODE, TO_DATE, TO_CHAR, SYSDATE -- most Oracle built-in functions have direct or near-direct Snowflake counterparts. MigryX's 2,000+ function mapping library handles the edge cases: DECODE to IFF/CASE, ROWNUM to ROW_NUMBER(), database links to external tables.
A PL/SQL query using DECODE, NVL, and Oracle-specific date functions -- converted to Snowflake SQL with IFF, COALESCE, and native date handling. Clean, idiomatic Snowflake output.
-- Procedure: generate_account_summary
CREATE OR REPLACE PROCEDURE generate_summary AS
v_run_date DATE := SYSDATE;
BEGIN
INSERT INTO account_summary
SELECT
a.account_id,
NVL(a.account_name, 'Unnamed'),
DECODE(a.account_type,
'SAV', 'Savings',
'CHK', 'Checking',
'LON', 'Loan',
'Other') AS type_label,
NVL2(a.close_date,
'Closed', 'Active') AS status,
TO_CHAR(a.open_date, 'YYYY-MM-DD'),
v_run_date
FROM accounts a
WHERE a.open_date >=
ADD_MONTHS(SYSDATE, -12)
AND ROWNUM <= 100000;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
ROLLBACK;
END;
-- PL/SQL procedure → Snowflake Scripting
CREATE OR REPLACE PROCEDURE generate_summary()
RETURNS STRING
LANGUAGE SQL
AS
$$
DECLARE
v_run_date DATE := CURRENT_DATE();
BEGIN
INSERT INTO account_summary
SELECT
a.account_id,
COALESCE(a.account_name, 'Unnamed'),
IFF(a.account_type = 'SAV', 'Savings',
IFF(a.account_type = 'CHK', 'Checking',
IFF(a.account_type = 'LON', 'Loan',
'Other'))) AS type_label,
IFF(a.close_date IS NOT NULL,
'Closed', 'Active') AS status,
TO_CHAR(a.open_date, 'YYYY-MM-DD'),
:v_run_date
FROM accounts a
WHERE a.open_date >=
DATEADD('MONTH', -12, CURRENT_DATE())
LIMIT 100000;
RETURN 'Success';
EXCEPTION
WHEN OTHER THEN
ROLLBACK;
RETURN SQLERRM;
END;
$$;
DECODE mapped to nested IFF. NVL mapped to COALESCE. NVL2 mapped to IFF with IS NOT NULL. SYSDATE mapped to CURRENT_DATE(). ADD_MONTHS mapped to DATEADD. ROWNUM mapped to LIMIT. DBMS_OUTPUT mapped to RETURN. Exception handling preserved.
| Oracle PL/SQL Component | Snowflake Equivalent | Notes |
|---|---|---|
| Stored Procedure | Snowflake Scripting procedure | DECLARE/BEGIN/EXCEPTION structure preserved |
| Package (spec + body) | Schema + stored procedures | Package functions become individual procedures |
| Function | Snowflake UDF / Snowpark UDF | Scalar and table functions supported |
| CONNECT BY hierarchical query | Recursive CTE | LEVEL, SYS_CONNECT_BY_PATH preserved |
| DECODE | IFF() / CASE WHEN | Multi-branch DECODE expanded to nested IFF |
| NVL / NVL2 | COALESCE() / IFF() | NVL2 mapped to IFF with null check |
| Trigger | Stream + Task | Change data capture via Snowflake Streams |
| Sequence | Snowflake SEQUENCE | Direct equivalent, syntax adjusted |
| Materialized View | Snowflake Materialized View | Direct equivalent with automatic refresh |
| DBMS_SCHEDULER | Snowflake Task | Cron scheduling with dependency trees |
| EXECUTE IMMEDIATE | EXECUTE IMMEDIATE | Direct equivalent in Snowflake Scripting |
| Cursor FOR loop | Snowflake cursor / RESULTSET | Procedural cursor iteration supported |
| Database Link | External Table / Data Share | Cross-database access pattern mapped |
| Synonym | View or alias | Object aliasing via views |
Data Matching compares Oracle output against Snowflake output -- row by row, column by column. In the case study below, all stored procedure results were validated with full production backtesting against the original Oracle database.
See how Data Matching works →6,200 PL/SQL objects converted to Snowflake SQL and Snowpark. 500 packages decomposed into Snowflake stored procedures and UDFs. CONNECT BY hierarchical queries rewritten as recursive CTEs. DECODE/NVL/NVL2 patterns mapped to Snowflake-native IFF/COALESCE. Oracle license costs eliminated, compute elasticity gained on day one.
Read the full case study →Upload a PL/SQL package or stored procedure. Get parsed lineage, Snowflake SQL code, and a validation report.