Stored procedures in PlanetScale are surprisingly powerful, but they don’t support every single SQL feature you might expect from a traditional database.
Let’s see how they actually work. Imagine you have a common task, like updating a user’s profile and then logging that change. Instead of writing two separate queries from your application, you can encapsulate that logic in a stored procedure.
DELIMITER $$
CREATE PROCEDURE UpdateUserProfileAndLog(
IN userId INT,
IN newEmail VARCHAR(255),
IN newBio TEXT
)
BEGIN
-- Start a transaction to ensure atomicity
START TRANSACTION;
-- Update the user's profile
UPDATE users
SET email = newEmail, bio = newBio
WHERE id = userId;
-- Log the update
INSERT INTO user_logs (user_id, action, timestamp)
VALUES (userId, 'profile_updated', NOW());
-- Commit the transaction
COMMIT;
END$$
DELIMITER ;
To call this procedure from your application (or directly in the PlanetScale SQL console):
CALL UpdateUserProfileAndLog(123, 'new.email@example.com', 'Updated my bio!');
This example demonstrates a basic UPDATE and INSERT, which are fully supported. The START TRANSACTION and COMMIT are also standard practice and work as expected within procedures.
The core of what’s supported revolves around standard SQL data manipulation language (DML) statements like SELECT, INSERT, UPDATE, and DELETE. You can also use DDL (Data Definition Language) statements like CREATE TABLE or ALTER TABLE within stored procedures, though this is less common and often managed through schema migration tools. Control flow statements such as IF, CASE, WHILE, and LOOP are also available, allowing for complex logic.
However, PlanetScale’s stored procedures have specific limitations. You won’t find support for features that are inherently tied to traditional, single-node database architectures or that could lead to distributed transaction complexities. This includes things like:
CREATE TRIGGER: You cannot define triggers within PlanetScale stored procedures. Triggers are a separate database object.CREATE EVENT: Scheduled events are not supported. PlanetScale’s architecture is built around distributed systems, and event scheduling would require a different management model.- Certain Transaction Isolation Levels: While you can use
START TRANSACTIONandCOMMIT, you can’t explicitly set isolation levels likeSET TRANSACTION ISOLATION LEVEL SERIALIZABLE. PlanetScale’s distributed nature has its own implicit handling of consistency. LOAD DATA INFILE: This command, typically used for bulk loading data from files on the database server, is not available in the context of stored procedures.SHOWstatements: Commands likeSHOW TABLES,SHOW DATABASES, orSHOW CREATE TABLEare not executable within stored procedures.- User-defined functions (UDFs) written in external languages: While you can call built-in SQL functions, you can’t define and call UDFs written in languages like Python or C++ directly within a PlanetScale stored procedure.
Understanding these limitations is crucial. For instance, if you’re migrating an application that heavily relies on triggers for auditing or data validation, you’ll need to refactor that logic into your application code or into stored procedures that are called explicitly.
The mental model to adopt is that PlanetScale stored procedures are designed for encapsulating business logic that operates on your data within the database, leveraging standard SQL constructs and control flow, but without delving into the operational or administrative aspects that are managed differently in a distributed, cloud-native database.
One significant aspect that often trips people up is the lack of explicit cursor support. While you can use SELECT statements to retrieve data, you can’t iterate over result sets row-by-row within a procedure using traditional cursor syntax. If you need to process data iteratively, you’ll often find yourself restructuring the logic to use set-based operations or by calling the procedure multiple times from your application with different parameters.
The next hurdle you’ll likely encounter is understanding how to manage the lifecycle of these stored procedures, especially when dealing with schema changes and versioning.