Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
A stored procedure is a named block of SQL that runs on the server. You call it once and it executes however many statements are inside. The code lives in the database, not in your application.

Creating a Stored Procedure

MySQL uses DELIMITER to change the statement terminator so the ; inside the procedure body doesn’t end the CREATE PROCEDURE statement early.
Call it with CALL:
Drop it:
View its definition:

Parameters

Procedures support three parameter modes:
Call it with a user-defined variable for OUT parameters:

Local Variables

Declare local variables with DECLARE at the top of the BEGIN...END block, before any other statements:

Control Flow

MySQL procedures support standard control flow constructs:

Error Handling

Use DECLARE ... HANDLER to catch errors:
EXIT HANDLER stops the procedure when the condition fires. CONTINUE HANDLER lets the procedure keep running. RESIGNAL re-raises the error to the caller. Raise your own errors with SIGNAL:
45000 is the SQLSTATE for “unhandled user-defined exception.”

Cursors

Cursors iterate over a result set row by row inside a procedure. Use them when you can’t express the logic as a set operation.
The NOT FOUND handler sets v_done when the cursor runs out of rows. Always close cursors before the procedure ends.

Stored Procedures vs Functions

Use a function when you need to embed the logic in a SQL expression. Use a procedure for everything else — multi-step processes, conditional logic, side effects.

When to Use Stored Procedures

Stored procedures make sense when:
  • Enforcing business rules that must apply regardless of which application or user runs the query
  • Reducing round trips for multi-step operations (complex batch jobs, data migrations)
  • Granting users access to specific operations without exposing underlying tables (GRANT EXECUTE ON PROCEDURE)
They hurt when:
  • The logic changes frequently — deployments require ALTER PROCEDURE or DROP/recreate
  • Debugging is needed — no debugger, only SIGNAL-based logging
  • Portability matters — stored procedure syntax is MySQL-specific

Frequently Asked Questions

Can a stored procedure return a result set?

Yes. Any SELECT inside a procedure that doesn’t use INTO sends a result set to the caller:
Multiple SELECT statements inside one procedure send multiple result sets. Most clients handle this but some ORMs don’t.

How do I see all stored procedures in a database?

Troubleshooting

VillageSQL: Custom Extension Types in Stored Procedures

VillageSQL custom extension types (e.g., COMPLEX, UUID, TVECTOR) can be used as stored procedure parameter types and DECLARE variable types. Install the extension first, then reference its types in your procedure definition:
UNINSTALL EXTENSION will fail while any stored procedure uses that extension’s custom types. Drop or alter the procedure before uninstalling the extension. See Uninstalling Extensions for details.

See also