Stored Procedures, UDFs, and Snowflake Scripting: A Practical Guide
Learn to create and use Snowflake stored procedures, UDFs, and Snowflake Scripting with production-ready examples, debugging tips, and best practices for developers..
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
- ✓Basic knowledge of SQL (SELECT, INSERT, UPDATE, DELETE).
- ✓A Snowflake account with access to create procedures and functions.
- ✓Familiarity with Snowflake's web interface or a SQL client.
- Stored procedures encapsulate business logic with multiple SQL statements and control flow.
- UDFs (User-Defined Functions) return a single value per call, ideal for reusable calculations.
- Snowflake Scripting extends SQL with variables, loops, and conditionals using JavaScript or SQL.
- Use stored procedures for complex ETL, UDFs for row-level transformations.
- Debug with system functions like SYSTEM$LOG and query history.
Think of stored procedures as a recipe that tells the kitchen staff (Snowflake) exactly how to prepare a meal step-by-step, including when to preheat the oven and how long to stir. UDFs are like a spice blend you can reuse in many recipes—you define it once and sprinkle it wherever needed. Snowflake Scripting is the language of the recipe itself, allowing you to write instructions like 'if the sauce is too thick, add water' or 'repeat the stirring step 5 times.'
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
Imagine you're a data engineer at a fast-growing e-commerce company. Every night, you need to clean raw sales data, calculate customer lifetime value, and load it into a reporting table. Without stored procedures, you'd manually run a dozen SQL statements in sequence, hoping you don't miss a step. With Snowflake stored procedures and UDFs, you can automate this entire pipeline, handle errors gracefully, and reuse logic across multiple workflows.
Snowflake's support for stored procedures and user-defined functions (UDFs) brings the power of procedural programming to your data warehouse. Whether you're migrating from traditional databases like PostgreSQL or building new data pipelines, understanding these features is essential for writing maintainable, efficient code. Snowflake Scripting, introduced in 2021, provides a native SQL-based language for writing stored procedures, reducing the need for JavaScript or Python.
In this tutorial, you'll learn how to create and use stored procedures and UDFs in Snowflake, with a focus on real-world scenarios. We'll cover Snowflake Scripting syntax, debugging techniques, and common pitfalls. By the end, you'll be able to automate complex data transformations, improve code reusability, and troubleshoot production issues like a pro.
1. Introduction to Snowflake Stored Procedures and UDFs
Snowflake stored procedures allow you to write procedural code that executes multiple SQL statements, supports conditional logic (IF/ELSE), loops (FOR, WHILE), and exception handling. They can be written in JavaScript (using Snowflake's JavaScript API) or Snowflake Scripting (a SQL-based procedural language). UDFs, on the other hand, are functions that return a single scalar value or a table. They are ideal for encapsulating reusable calculations or transformations that can be used in SELECT statements.
When should you use each? Use stored procedures for tasks that require multiple steps, such as ETL pipelines, data validation, or administrative operations. Use UDFs for row-level computations, like calculating discounted prices or formatting strings. Both support parameters and can be called from SQL.
Snowflake Scripting is the recommended approach for new development because it integrates seamlessly with SQL and is easier to read and maintain. However, JavaScript procedures offer more flexibility for complex logic and integration with external APIs.
In this section, we'll create a simple stored procedure and a UDF to get started.
2. Snowflake Scripting: Variables, Cursors, and Control Flow
Snowflake Scripting introduces variables, cursors, and control flow constructs that make procedural programming possible. Variables are declared using DECLARE or LET, and can be of any Snowflake data type. Cursors allow you to iterate over query results row by row. Control flow includes IF/ELSE, FOR, WHILE, and REPEAT loops.
Let's build a procedure that processes orders and updates inventory. This example demonstrates variables, a cursor, and a loop.
3. Creating and Using User-Defined Functions (UDFs)
UDFs in Snowflake can be scalar (return a single value) or tabular (return a table). They can be written in SQL, JavaScript, Python, or Java. SQL UDFs are the simplest and most performant for simple calculations. JavaScript UDFs allow more complex logic, such as string manipulation or date arithmetic.
Here's an example of a SQL UDF that calculates the number of business days between two dates, excluding weekends.
4. Stored Procedures for ETL: A Real-World Example
ETL (Extract, Transform, Load) pipelines are a common use case for stored procedures. Let's build a procedure that extracts raw sales data from a staging table, transforms it by calculating commissions, and loads it into a reporting table. This example uses Snowflake Scripting with error handling and logging.
5. JavaScript Stored Procedures: When and How to Use Them
JavaScript stored procedures offer more flexibility than Snowflake Scripting, especially for complex logic, external API calls, or when you need to use JavaScript libraries. However, they require understanding Snowflake's JavaScript API, which includes methods like snowflake.execute(), snowflake.createStatement(), and resultSet.
Here's an example of a JavaScript procedure that calls an external API (simulated) to enrich customer data.
6. Debugging and Monitoring Stored Procedures and UDFs
Debugging stored procedures in Snowflake can be challenging because you cannot step through code interactively. However, you can use several techniques: - Use SYSTEM$LOG to insert log messages into a table. - Query the QUERY_HISTORY view to see the SQL statements executed by the procedure. - Use the GET_DDL function to review the procedure definition. - For JavaScript procedures, use console.log() (output appears in the query profile).
Here's an example of logging within a Snowflake Scripting procedure.
7. Best Practices and Performance Considerations
When writing stored procedures and UDFs, follow these best practices: - Use set-based operations instead of cursors whenever possible. - Limit the number of DDL statements inside procedures; they consume more resources. - Use temporary tables for intermediate results to avoid locking. - Mark UDFs as IMMUTABLE or STABLE to enable caching. - Avoid using UDFs in WHERE clauses on large tables. - Use exception handling to catch errors and rollback if necessary. - Monitor procedure execution with Snowflake's QUERY_HISTORY and ACCOUNT_USAGE views.
- Stored procedures run in a single session; long-running procedures may hit timeouts.
- Use the STATEMENT_TIMEOUT_IN_SECONDS parameter to control timeouts.
- For large data volumes, consider using Snowflake's tasks and streams instead of procedures.
- UDFs that are used in many rows can be slow; consider using built-in functions or rewriting as joins.
The Midnight ETL Failure: A Stored Procedure Timeout
- Always test stored procedures with production-scale data volumes.
- Use explicit transaction control (COMMIT) to break long-running operations into smaller chunks.
- Set appropriate timeout values using Snowflake parameters like STATEMENT_TIMEOUT_IN_SECONDS.
- Monitor procedure execution with SYSTEM$CURRENT_USER_TASK_NAME and query history.
- Implement logging within procedures to track progress and catch failures early.
ALTER SESSION SET STATEMENT_TIMEOUT_IN_SECONDS = 3600;CALL MY_PROCEDURE();| File | Command / Code | Purpose |
|---|---|---|
| basic_procedure_udf.sql | CREATE OR REPLACE PROCEDURE greet_user(user_name VARCHAR) | 1. Introduction to Snowflake Stored Procedures and UDFs |
| scripting_example.sql | CREATE OR REPLACE PROCEDURE process_orders() | 2. Snowflake Scripting |
| business_days_udf.sql | CREATE OR REPLACE FUNCTION business_days(start_date DATE, end_date DATE) | 3. Creating and Using User-Defined Functions (UDFs) |
| etl_procedure.sql | CREATE OR REPLACE PROCEDURE etl_sales_pipeline() | 4. Stored Procedures for ETL |
| javascript_procedure.js | CREATE OR REPLACE PROCEDURE enrich_customer_data(customer_id INT) | 5. JavaScript Stored Procedures |
| debugging_procedure.sql | CREATE OR REPLACE TABLE proc_log ( | 6. Debugging and Monitoring Stored Procedures and UDFs |
| best_practices.sql | UPDATE inventory i | 7. Best Practices and Performance Considerations |
Key takeaways
Common mistakes to avoid
5 patternsNot using COMMIT in long-running procedures, causing timeouts.
Using cursors for large datasets instead of set-based operations.
Creating UDFs without specifying volatility (IMMUTABLE/STABLE/VOLATILE).
Using UDFs in WHERE clauses on large tables.
Not handling exceptions in stored procedures.
Interview Questions on This Topic
Explain the difference between a stored procedure and a UDF in Snowflake.
Frequently Asked Questions
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
That's Snowflake. Mark it forged?
3 min read · try the examples if you haven't