SQL Custom Function Guide
SQL user-defined functions (SQL UDFs) let you encapsulate reusable computation logic in SQL expressions and call them just like built-in functions in your queries.
When to Use Which Type
| Type | Use Case | Limitations |
|---|---|---|
| SQL Function (this article) | Pure SQL logic: data cleansing, calculation formulas, conditional logic | SQL expressions only; cannot call external services |
| External Function | Requires Python/Java code, external APIs, or ML models | Requires deploying an external service |
| Built-in Function | Standard math, string, and date operations | Not customizable |
When to use a SQL Function:
- The same computation logic appears repeatedly across multiple queries
- Business rules need centralized maintenance (e.g., discount calculations, classification rules)
- You need to encapsulate complex CASE WHEN logic or multi-step calculations
SQL Commands Involved
| Command | Purpose |
|---|---|
CREATE FUNCTION | Create a scalar function or table function |
CREATE OR REPLACE FUNCTION | Update an existing function definition |
DROP FUNCTION | Delete a function |
DESC FUNCTION | View a function definition |
SHOW EXTERNAL FUNCTIONS | List custom functions in the current schema |
Prerequisites
Scenario 1: Scalar Function — Encapsulating a Calculation Formula
Goal: Centralize discount calculation logic so it stays consistent wherever it is called.
| order_id | amount | discounted |
|---|---|---|
| 1 | 99.9 | 89.91 |
| 4 | 199.0 | 179.1 |
Scenario 2: Scalar Function — Encapsulating Classification Rules
Goal: Tier orders by amount with centrally maintained rules.
| order_id | amount | tier |
|---|---|---|
| 2 | 299.0 | Premium |
| 4 | 199.0 | Standard |
| 1 | 99.9 | Standard |
| 3 | 49.5 | Basic |
| 5 | 0.0 | Free |
Scenario 3: Scalar Function — Data Cleansing
Goal: Cleanse phone numbers by removing non-digit characters.
Scenario 4: Table Function — Returning Multiple Rows
A Table Function returns a virtual table that can be used like a table in a FROM clause.
Goal: Generate a consecutive date sequence to populate a calendar dimension.
| dt |
|---|
| 2024-01-01 |
| 2024-01-02 |
| 2024-01-03 |
| 2024-01-04 |
| 2024-01-05 |
| dt | daily_revenue |
|---|---|
| 2024-01-01 | 99.9 |
| 2024-01-02 | 0 |
| 2024-01-03 | 348.5 |
| 2024-01-04 | 0 |
| 2024-01-05 | 199 |
Function Management
View a Function Definition
Returns the function name, creation time, full SQL definition, and other information.
Update a Function
Use CREATE OR REPLACE FUNCTION to overwrite directly without dropping first:
Drop a Function
Notes
- Schema prefix is required: You must write
schema_name.function_namewhen calling a function, otherwise a "function not found" error will be returned. You can change the resolution policy viaSET cz.sql.remote.udf.lookup.policy = builtin_first. See SET (Session Parameters). - Default parameters must come last: Parameters with default values must be placed after parameters without default values.
- Table functions must use a query: The body of a
RETURNS TABLEfunction can only be aSELECTstatement, not an expression. - DML is not supported in function bodies: SQL functions cannot execute INSERT/UPDATE/DELETE.
- Recursion is not supported: A function body cannot call itself; doing so will result in a "function not found" error.
- Calling other custom functions is allowed: A function body can call other SQL functions in the same schema, using the schema prefix.
- When a name conflicts with a built-in function: Call the custom function with the schema prefix; call the built-in function without a prefix. The two do not interfere with each other.
- NULL inputs: NULL arguments participate in CASE WHEN evaluation;
NULL >= 200is false, so execution falls through to the ELSE branch. OR REPLACEandIF NOT EXISTScannot be used together: This will cause a syntax error.
