Skip to main content
If you’re coming from a traditional relational database, you may be looking for stored procedures and prepared statements in ClickHouse. This guide explains ClickHouse’s approach to these concepts and provides recommended alternatives.

Alternatives to stored procedures in ClickHouse

ClickHouse doesn’t support traditional stored procedures with control flow logic (IF/ELSE, loops, etc.). This is an intentional design decision based on ClickHouse’s architecture as an analytical database. Loops are discouraged for analytical databases because processing O(n) simple queries is usually slower than processing fewer complex queries. ClickHouse is optimized for:
  • Analytical workloads - Complex aggregations over large datasets
  • Batch processing - Handling large data volumes efficiently
  • Declarative queries - SQL queries that describe what data to retrieve, not how to process it
Stored procedures with procedural logic work against these optimizations. Instead, ClickHouse provides alternatives that align with its strengths.

User-Defined Functions (UDFs)

User-Defined Functions let you encapsulate reusable logic without control flow. ClickHouse supports two types:

Lambda-based UDFs

Create functions using SQL expressions and lambda syntax:
Limitations:
  • No loops or complex control flow
  • Can’t modify data (INSERT/UPDATE/DELETE)
  • Recursive functions not allowed
See CREATE FUNCTION for complete syntax.

Executable UDFs

For more complex logic, use executable UDFs that call external programs:
Executable UDFs can implement arbitrary logic in any language (Python, Node.js, Go, etc.). See Executable UDFs for details.

Parameterized views

Parameterized views act like functions that return datasets. They’re ideal for reusable queries with dynamic filtering:

Common use cases

See the Parameterized Views section for more information.

Materialized views

Materialized views are ideal for pre-computing expensive aggregations that would traditionally be done in stored procedures. If you’re coming from a traditional database, think of a materialized view as an INSERT trigger that automatically transforms and aggregates data as it’s inserted into the source table:

Refreshable materialized views

For scheduled batch processing (like nightly stored procedures):
See Cascading Materialized Views for advanced patterns.

External orchestration

For complex business logic, ETL workflows, or multi-step processes, it’s always possible to implement logic outside ClickHouse, using language clients.

Using application code

Here’s a side-by-side comparison showing how a MySQL stored procedure translates to application code with ClickHouse:

Key differences

  1. Control flow - MySQL stored procedure uses IF/ELSE, WHILE loops. In ClickHouse, implement this logic in your application code (Python, Java, etc.)
  2. Transactions - MySQL supports BEGIN/COMMIT/ROLLBACK for ACID transactions. ClickHouse is an analytical database optimized for append-only workloads, not transactional updates
  3. Updates - MySQL uses UPDATE statements. ClickHouse prefers INSERT with ReplacingMergeTree or CollapsingMergeTree for mutable data
  4. Variables and state - MySQL stored procedures can declare variables (DECLARE v_discount). With ClickHouse, manage state in your application code
  5. Error handling - MySQL supports SIGNAL and exception handlers. In application code, use your language’s native error handling (try/catch)
When to use each approach:
  • OLTP workloads (orders, payments, user accounts) → Use MySQL/PostgreSQL with stored procedures
  • Analytics workloads (reporting, aggregations, time-series) → Use ClickHouse with application orchestration
  • Hybrid architecture → Use both! Stream transactional data from OLTP to ClickHouse for analytics

Using workflow orchestration tools

  • Apache Airflow - Schedule and monitor complex DAGs of ClickHouse queries
  • dbt - Transform data with SQL-based workflows
  • Prefect/Dagster - Modern Python-based orchestration
  • Custom schedulers - Cron jobs, Kubernetes CronJobs, etc.
Benefits of external orchestration:
  • Full programming language capabilities
  • Better error handling and retry logic
  • Integration with external systems (APIs, other databases)
  • Version control and testing
  • Monitoring and alerting
  • More flexible scheduling

Alternatives to prepared statements in ClickHouse

While ClickHouse doesn’t have traditional “prepared statements” in the RDBMS sense, it provides query parameters that serve the same purpose: safe, parameterized queries that prevent SQL injection.

Syntax

There are two ways to define query parameters:

Method 1: using SET

Method 2: using CLI parameters

Parameter syntax

Parameters are referenced using: {parameter_name: DataType}
  • parameter_name - The name of the parameter (without the param_ prefix)
  • DataType - The ClickHouse data type to cast the parameter to

Data type examples


For use of query parameters in language clients, refer to the documentation for the specific language client you’re interested in.

Limitations of query parameters

Query parameters are not general text substitutions. They have specific limitations:
  1. They’re primarily intended for SELECT statements - the best support is in SELECT queries
  2. They work as identifiers or literals - they can’t substitute arbitrary SQL fragments
  3. They have limited DDL support - they’re supported in CREATE TABLE, but not in ALTER TABLE
What WORKS:
What DOESN’T work:

Security best practices

Always use query parameters for user input:
Validate input types:

MySQL protocol prepared statements

ClickHouse’s MySQL interface includes minimal support for prepared statements (COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_CLOSE), primarily to enable connectivity with tools like Tableau Online that wrap queries in prepared statements. Key limitations:
  • Parameter binding isn’t supported - You can’t use ? placeholders with bound parameters
  • Queries are stored but not parsed during PREPARE
  • Implementation is minimal and designed for specific BI tool compatibility
Example of what doesn’t work:
Use ClickHouse’s native query parameters instead. They provide full parameter binding support, type safety, and SQL injection prevention across all ClickHouse interfaces:
For more details, see the MySQL Interface documentation and the blog post on MySQL support.

Summary

ClickHouse alternatives to stored procedures

Use of query parameters

Query parameters can be used for:
  • Preventing SQL injection
  • Parameterized queries with type safety
  • Dynamic filtering in applications
  • Reusable query templates
Last modified on June 12, 2026