19.2.1. CREATE PROCEDURE and CREATE FUNCTION Syntax
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
func_parameter:
param_name type
type:
Any valid MySQL data type
characteristic:
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
routine_body:
Valid SQL procedure statement
These statements create stored routines. To use them, it is
necessary to have the CREATE ROUTINE
privilege. If binary logging is enabled, the CREATE
FUNCTION statement might may also require the
SUPER privilege, as described in
Section 19.4, “Binary Logging of Stored Routines and Triggers”. MySQL automatically
grants the ALTER ROUTINE and
EXECUTE privileges to the routine creator.
By default, the routine is associated with the default database.
To associate the routine explicitly with a given database,
specify the name as db_name.sp_name
when you create it.
If the routine name is the same as the name of a built-in SQL
function, you must use a space between the name and the
following parenthesis when defining the routine, or a syntax
error occurs. This is also true when you invoke the routine
later. For this reason, we suggest that it is better to avoid
re-using the names of existing SQL functions for your own stored
routines.
The IGNORE_SPACE SQL mode applies to built-in
functions, not to stored routines. it is always allowable to
have spaces after a routine name, regardless of whether
IGNORE_SPACE is enabled.
The parameter list enclosed within parentheses must always be
present. If there are no parameters, an empty parameter list of
() should be used. Each parameter is an
IN parameter by default. To specify otherwise
for a parameter, use the keyword OUT or
INOUT before the parameter name.
Note: Specifying a parameter as
IN, OUT, or
INOUT is valid only for a
PROCEDURE. (FUNCTION
parameters are always regarded as IN
parameters.)
Each parameter can be declared to use any valid data type,
except that the COLLATE attribute cannot be
used.
The RETURNS clause may be specified only for
a FUNCTION, for which it is mandatory. It
indicates the return type of the function, and the function body
must contain a RETURN
value statement.
The routine_body consists of a valid
SQL procedure statement. This can be a simple statement such as
SELECT or INSERT, or it
can be a compound statement written using
BEGIN and END. Compound
statement syntax is described in Section 19.2.5, “BEGIN ... END Compound Statement Syntax”.
Compound statements can contain declarations, loops, and other
control structure statements. The syntax for these statements is
described later in this chapter. See, for example,
Section 19.2.6, “DECLARE Statement Syntax”, and
Section 19.2.10, “Flow Control Constructs”. Some statements are
not allowed in stored routines; see
Section I.1, “Restrictions on Stored Routines and Triggers”.
The CREATE FUNCTION statement was used in
earlier versions of MySQL to support UDFs (user-defined
functions). See Section 27.3, “Adding New Functions to MySQL”. UDFs
continue to be supported, even with the existence of stored
functions. A UDF can be regarded as an external stored function.
However, do note that stored functions share their namespace
with UDFs.
A procedure or function is considered
“deterministic” if it always produces the same
result for the same input parameters, and “not
deterministic” otherwise. If neither
DETERMINISTIC nor NOT
DETERMINISTIC is given in the routine definition, the
default is NOT DETERMINISTIC.
For replication purposes, use of the NOW()
function (or its synonyms) or RAND() does not
necessarily make a routine non-deterministic. For
NOW(), the binary log includes the timestamp
and replicates correctly. RAND() also
replicates correctly as long as it is invoked only once within a
routine. (You can consider the routine execution timestamp and
random number seed as implicit inputs that are identical on the
master and slave.)
Currently, the DETERMINISTIC characteristic
is accepted, but not yet used by the optimizer. However, if
binary logging is enabled, this characteristic affects which
routine definitions MySQL accepts. See
Section 19.4, “Binary Logging of Stored Routines and Triggers”.
Several characteristics provide information about the nature of
data use by the routine. CONTAINS SQL
indicates that the routine does not contain statements that read
or write data. NO SQL indicates that the
routine contains no SQL statements. READS SQL
DATA indicates that the routine contains statements
that read data, but not statements that write data.
MODIFIES SQL DATA indicates that the routine
contains statements that may write data. CONTAINS
SQL is the default if none of these characteristics is
given explicitly. These characteristics are advisory only. The
server does not use them to constrain what kinds of statements a
routine will be allowed to execute.
The SQL SECURITY characteristic can be used
to specify whether the routine should be executed using the
permissions of the user who creates the routine or the user who
invokes it. The default value is DEFINER.
This feature is new in SQL:2003. The creator or invoker must
have permission to access the database with which the routine is
associated. It is necessary to have the
EXECUTE privilege to be able to execute the
routine. The user that must have this privilege is either the
definer or invoker, depending on how the SQL
SECURITY characteristic is set.
MySQL stores the sql_mode system variable
setting that is in effect at the time a routine is created, and
always executes the routine with this setting in force.
When the routine is invoked, an implicit USE
db_name is performed (and
undone when the routine terminates). USE
statements within stored routines are disallowed.
The server uses the data type of a routine parameter or function
return value as follows. These rules also apply to local routine
variables created with the DECLARE statement
(Section 19.2.7.1, “DECLARE Local Variables”).
Assignments are checked for data type mismatches and
overflow. Conversion and overflow problems result in
warnings, or errors in strict mode.
For character data types, if there is a CHARACTER
SET clause in the declaration, the specified
character set and its default collation are used. If there
is no such clause, the database character set and collation
are used. (These are given by the values of the
character_set_database and
collation_database system variables.)
Only scalar values can be assigned to parameters or
variables. For example, a statement such as SET x =
(SELECT 1, 2) is invalid.
The COMMENT clause is a MySQL extension, and
may be used to describe the stored routine. This information is
displayed by the SHOW CREATE PROCEDURE and
SHOW CREATE FUNCTION statements.
MySQL allows routines to contain DDL statements, such as
CREATE and DROP. MySQL
also allows stored procedures (but not stored functions) to
contain SQL transaction statements such as
COMMIT. Stored functions may not contain
statements that do explicit or implicit commit or rollback.
Support for these statements is not required by the SQL
standard, which states that each DBMS vendor may decide whether
to allow them.
Stored routines cannot use LOAD DATA INFILE.
Statements that return a result set cannot be used within a
stored function. This includes SELECT
statements that do not use INTO to fetch
column values into variables, SHOW
statements, and other statements such as
EXPLAIN. For statements that can be
determined at function definition time to return a result set, a
Not allowed to return a result set from a
function error occurs
(ER_SP_NO_RETSET_IN_FUNC). For statements
that can be determined only at runtime to return a result set, a
PROCEDURE %s can't return a result set in the given
context error occurs
(ER_SP_BADSELECT).
The following is an example of a simple stored procedure that
uses an OUT parameter. The example uses the
mysql client delimiter
command to change the statement delimiter from
; to // while the
procedure is being defined. This allows the ;
delimiter used in the procedure body to be passed through to the
server rather than being interpreted by mysql
itself.
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
When using the delimiter command, you should
avoid the use of the backslash
(‘\’) character because that is
the escape character for MySQL.
The following is an example of a function that takes a
parameter, performs an operation using an SQL function, and
returns the result. In this case, it is unnecessary to use
delimiter because the function definition
contains no internal ; statement delimiters:
mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
-> RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world! |
+----------------+
1 row in set (0.00 sec)
A stored function returns a value of the data type specified in
its RETURNS clause. If the
RETURN statement returns a value of a
different type, the value is coerced to the proper type. For
example, if a function returns an ENUM or
SET value, but the RETURN
statement returns an integer, the value returned from the
function is the string for the corresponding
ENUM member of set of SET
members.