Snowflake

UDFs & Stored Procedures: Complete Guide to Snowflake Custom Logic

2026-03-21
更新: 2026-03-27
NicheeLab Editorial Team

In Snowflake, custom logic that goes beyond the built-in functions is implemented with UDFs (User Defined Functions) and Stored Procedures. UDFs are used inside SELECT statements to transform or compute values, while Stored Procedures are invoked with CALL and can run complex flows that include DDL and DML.

This article gives a comprehensive walkthrough of the differences between UDFs and Stored Procedures, the CREATE syntax in each supported language, Vectorized UDFs, and the privilege models (Caller's Rights / Owner's Rights). These topics show up frequently in the Data Transformation domain of the SnowPro Core exam.

UDF vs Stored Procedure Comparison

Here are the differences between UDFs and Stored Procedures at a glance. The SnowPro exam frequently asks which one fits a given situation.

AspectUDFStored Procedure
How to invokeCalled inside SELECT (SELECT my_udf(col))Called with CALL (CALL my_proc())
DDL/DML executionNot allowed (side-effect free)Allowed (CREATE/INSERT/UPDATE/DELETE)
Side effectsNone (must be side-effect free)Allowed (can change DB state)
Return valueScalar value or table (UDTF)Single scalar value
GRANT syntaxGRANT USAGE ON FUNCTIONGRANT USAGE ON PROCEDURE
Privilege modelRuns with caller's privilegesOwner's Rights (default) / Caller's Rights
TransactionsRuns inside the caller's transactionCan manage its own transactions
Where it can be usedSELECT / WHERE / JOIN / HAVING clausesCALL only (cannot be used inside SELECT)

UDF Types: Scalar UDFs and Table UDFs (UDTFs)

Scalar UDF

Takes one or more input values and returns a single value. It can be used anywhere — in the SELECT list, WHERE clause, JOIN conditions, and more — for things like custom hash functions or business-rule calculations.

-- SQL scalar UDF: tax-inclusive price calculation
CREATE OR REPLACE FUNCTION calc_tax_price(price NUMBER, tax_rate NUMBER)
RETURNS NUMBER(12,2)
LANGUAGE SQL
AS
$
  price * (1 + tax_rate)
$;

-- Example usage
SELECT product_name, calc_tax_price(price, 0.10) AS tax_included
FROM products;

Table UDF (UDTF)

A function that returns a tabular result (multiple rows and columns). It is invoked in the FROM clause as TABLE(my_udtf(args)), and is used for unpivoting one input row into many output rows, or for aggregations that span multiple rows.

-- Python UDTF: split a CSV string into rows
CREATE OR REPLACE FUNCTION split_csv(csv_string VARCHAR)
RETURNS TABLE(item VARCHAR)
LANGUAGE PYTHON
RUNTIME_VERSION = '3.11'
HANDLER = 'SplitCSV'
AS
$
class SplitCSV:
    def process(self, csv_string):
        for item in csv_string.split(','):
            yield (item.strip(),)
$;

-- Example usage
SELECT t.item
FROM my_table, TABLE(split_csv(my_table.tags)) t;

Language Support Matrix

LanguageScalar UDFUDTFVectorized UDFStored ProcedureNotes
SQLYesYes-Yes (Snowflake Scripting)Lightest weight; no external runtime
PythonYesYesYesYesSnowpark integration; great for ML / data science
JavaScriptYesYes-YesHistorically the first language supported
JavaYesYesYesYesRuns on the JVM; enterprise-friendly
ScalaYesYesYesYesRuns on the JVM; familiar to Spark users

Vectorized UDFs (Pandas UDFs)

Vectorized UDFs are the high-performance variant of Python UDFs. While a regular scalar UDF calls the Python function once per row, a Vectorized UDF receives input as a batch of pandas.Series and uses vectorized operations. Expect 5-50x throughput gains on numeric computation over large row counts.

-- Vectorized UDF: receive pandas.Series and process in batches
CREATE OR REPLACE FUNCTION normalize_score(score NUMBER)
RETURNS NUMBER
LANGUAGE PYTHON
RUNTIME_VERSION = '3.11'
PACKAGES = ('pandas')
HANDLER = 'normalize'
AS
$
import pandas as pd

def normalize(score: pd.Series) -> pd.Series:
    return (score - score.mean()) / score.std()
$;

With Snowpark, you can define the equivalent Vectorized UDF by setting PandasSeries in theinput_types argument of the @udf decorator.

Stored Procedure Implementation Patterns

A Stored Procedure is program logic invoked with CALL. It can implement complex flows that include DDL/DML execution, transaction control, conditional branching, and exception handling.

-- Snowflake Scripting (SQL) Stored Procedure
CREATE OR REPLACE PROCEDURE archive_old_orders(cutoff_date DATE)
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS OWNER
AS
$
BEGIN
  INSERT INTO orders_archive
    SELECT * FROM orders WHERE order_date < :cutoff_date;
  DELETE FROM orders WHERE order_date < :cutoff_date;
  RETURN 'Archived orders before ' || :cutoff_date;
EXCEPTION
  WHEN OTHER THEN
    ROLLBACK;
    RETURN 'Error: ' || SQLERRM;
END;
$;

-- Run
CALL archive_old_orders('2025-01-01');

Privilege Model: Owner's Rights vs Caller's Rights

AspectOwner's Rights (default)Caller's Rights
Execution privilegesThe Stored Procedure owner's roleThe caller's role
How to specifyEXECUTE AS OWNER (default)EXECUTE AS CALLER
Access scopeObjects the owner can accessObjects the caller can access
Privilege escalationPossible (runs with broader rights than the caller)None (stays with the caller's rights)
Use casesRestricted data operations; writing audit logsGeneric utilities; dynamic SQL
-- Example of Caller's Rights
CREATE OR REPLACE PROCEDURE list_tables(db_name VARCHAR)
RETURNS TABLE(table_name VARCHAR)
LANGUAGE SQL
EXECUTE AS CALLER
AS
$
BEGIN
  RETURN TABLE(
    SELECT table_name FROM information_schema.tables
    WHERE table_catalog = :db_name
  );
END;
$;

Authoring with Snowpark

With the Snowpark API, you define functions using the @udf, @udtf, and @sproc decorators and register them in Snowflake through the session.

  • Snowflake type mappings are generated automatically from Python type hints
  • Specify third-party packages via the packages parameter
  • Upload custom modules via the imports parameter
  • Use is_permanent=True to persist as a permanent UDF/Stored Procedure

Sample Question

UDF vs Stored Procedure

問題 1

Which statement correctly describes how a Snowflake Stored Procedure behaves when created with EXECUTE AS OWNER (the default)?

  1. The SQL inside the procedure runs with the caller's role privileges, so it cannot operate on tables the caller cannot access
  2. The SQL runs with the procedure owner's role, so it can operate on tables the caller cannot access as long as the owner has access
  3. It runs with ACCOUNTADMIN privileges and can therefore access every object
  4. Specifying EXECUTE AS OWNER lets you call the procedure inside SELECT just like a UDF

正解: B

Owner's Rights (EXECUTE AS OWNER) is the default privilege model for Stored Procedures. SQL inside the procedure runs with the owner role's privileges, so it can operate on tables the caller cannot access directly, as long as the owner has the necessary privileges. This lets you allow data operations through controlled business logic without granting regular users direct table access. Caller's Rights (EXECUTE AS CALLER), in contrast, runs with the caller's role and does not allow privilege escalation.

Practice UDF & Stored Procedure questions

Test your SnowPro readiness with our bilingual question bank

Try free questions

Frequently Asked Questions

What is the biggest difference between a UDF and a Stored Procedure?

The biggest differences are how you call them and whether side effects are allowed. A UDF is called inside a SELECT statement like a built-in function and returns a value. It cannot run DDL/DML and must be side-effect free. A Stored Procedure, in contrast, is invoked with CALL and can run DDL/DML such as CREATE TABLE, INSERT, UPDATE, and DELETE. UDFs always run with the caller's privileges, while Stored Procedures have two rights models — Owner's Rights (default) and Caller's Rights — switchable via the EXECUTE AS CALLER clause. For grants, UDFs use GRANT USAGE ON FUNCTION and Stored Procedures use GRANT USAGE ON PROCEDURE.

When are Vectorized UDFs (Pandas UDFs) most effective?

Vectorized UDFs are most effective for numeric computation and string transformation over large row counts. A regular scalar UDF invokes the Python interpreter for every row, so once you exceed roughly one million rows the function-call overhead dominates. Vectorized UDFs receive input as batches of pandas.Series (a few thousand rows by default) and leverage vectorized NumPy/pandas operations, delivering 5-50x throughput improvements compared to scalar UDFs. You enable them either by specifying the _sf_vectorized_input handler hint in CREATE FUNCTION, or via Snowpark's @udf(input_types=[PandasSeries[int]]) decorator.

When should I use Caller's Rights versus Owner's Rights?

Use Owner's Rights (the default) when you want callers to safely operate on tables they cannot access directly, routing them through the Stored Procedure. For example, you may not want to grant regular users direct UPDATE privileges and instead only allow updates that flow through specific business logic. Caller's Rights (EXECUTE AS CALLER) runs with the caller's privileges and is well suited to generic utility procedures (fetching table metadata, writing logs, etc.). On the security side, Owner's Rights carries a privilege-escalation risk: keep grants on the procedure owner role to a minimum, and verify the caller with CURRENT_ROLE() or IS_ROLE_IN_SESSION().

Related UDF & Stored Procedure Articles

Snowpark: Complete Guide

Data processing with Snowpark in Python and Scala

Snowflake Certifications Overview

Compare every Snowflake certification by scope, cost, and difficulty

Snowflake Glossary

80 must-know terms for the exam

Check what you learned with practice questions

Practice with certification-focused question sets

無料で問題を解いてみる
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Snowflake

Snowflake Certifications: All 11 Exams Explained (2026)

Every SnowPro certification — Associate, Core, Specialty, Ad...

Snowflake

Snowflake Exam Difficulty Ranking: All 11 Certs Compared (2026)

All 11 SnowPro exams ranked by difficulty with study-time es...

Snowflake

Snowflake Study Guide: Fastest Pass Route by Exam (2026)

How to pass SnowPro certifications efficiently — official ma...

Snowflake

SnowPro Core (COF-C03): Complete Exam Guide (2026)

Pass the SnowPro Core exam — six domains, scope, sample ques...

Snowflake

SnowPro Associate Platform (SOL-C01): Complete Guide (2026)

The entry-level SnowPro Associate exam — scope, weighting, s...

Browse all Snowflake articles (103)
© 2026 NicheeLab All rights reserved.