- Functions return a value, and procedures do not return a value.
- Procedures must be invoked using a statement. Functions can be invoked in nearly any context, such as
SELECT,FROM, andWHEREclauses, expressions, and expressions. - Functions have settings, and procedures do not.
Structure
A stored procedure consists of a name, optional parameters, language, and procedure body.- Each parameter can be a supported , , or the PL/pgSQL
REFCURSORtype, when . - CockroachDB supports the
IN(default),OUT, andINOUTmodes for parameters. For an example, see . LANGUAGEspecifies the language of the function body. CockroachDB supports the languages and .- The procedure body:
- Can be enclosed in single or dollar (
$$) quotes. Dollar quotes are easier to use than single quotes, which require that you escape other single quotes that are within the procedure body. - Must conform to a if written in PL/pgSQL.
- Can be enclosed in single or dollar (
Examples
Setup
To follow along, run to start a temporary, in-memory cluster with the sample dataset preloaded:Create a stored procedure using PL/pgSQL
The following stored procedure removes a specified number of earliest rides invehicle_location_histories.
It uses the syntax to iterate through the rows, [RAISE] to return notice and error messages, and REFCURSOR to define a cursor that fetches the next rows to be affected by the procedure.
rides_left cursor name:
vehicle_location_histories:
Example details
The example works as follows: defines a stored procedure calleddelete_earliest_histories with an INT and a REFCURSOR parameter.
LANGUAGE specifies as the language for the stored procedure.
DECLARE specifies the that are used in the procedure body.
BEGIN and END in the procedure body.
vehicle_location_histories has fewer rows than the number specified with num_deletions. If the exception is raised within an open transaction, the transaction will abort.
vehicle_location_histories, stopping when the number of loops reaches the num_deletions value.
The DELETE... RETURNING... INTO statement assigns column values from each deleted row into separate variables. For more information about assigning variables, see .
Finally, the statement reports these values for each deleted row.
OPEN statement for all remaining rows in vehicle_location_histories, sorted by timestamp. After calling the procedure in an open transaction, the cursor can be used to fetch rows from the table.
Alter a stored procedure
The following statement renames the todelete_histories:
Known limitations
Stored procedures have the following limitations:COMMITandROLLBACKstatements are not supported within nested procedures.- Routines cannot be invoked with named arguments, e.g.,
SELECT foo(a => 1, b => 2);orSELECT foo(b:= 1, a:= 2);. - Routines cannot be created if they reference temporary tables.
- Routines cannot be created with unnamed
INOUTparameters. For example,CREATE PROCEDURE p(INOUT INT) AS $$ BEGIN NULL; END; $$ LANGUAGE PLpgSQL;. - Routines cannot be created if they return fewer columns than declared. For example,
CREATE FUNCTION f(OUT sum INT, INOUT a INT, INOUT b INT) LANGUAGE SQL AS $$ SELECT (a + b, b); $$;. - Routines cannot be created with an
OUTparameter of typeRECORD. - DDL statements (e.g.,
CREATE TABLE,CREATE INDEX) are not allowed within UDFs or stored procedures. - Polymorphic types cannot be cast to other types (e.g.,
TEXT) within routine parameters.

