CREATE
[DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE
[DEFINER = { user | CURRENT_USER }]
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. By default, a 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.
When the routine is invoked, an implicit USE
is performed (and
undone when the routine terminates). The causes the routine to
have the given default database while it executes.
db_nameUSE statements within stored routines are
disallowed.
When a stored function has been created, you invoke it by
referring to it in an expression. The function returns a value
during expression evaluation. When a stored procedure has been
created, you invoke it by using the CALL
statement (see Section 12.2.1, “CALL Statement Syntax”).
As of MySQL 5.0.3, to execute the CREATE
PROCEDURE or CREATE FUNCTION
statement, it is necessary to have the CREATE
ROUTINE privilege. By default, MySQL automatically
grants the ALTER ROUTINE and
EXECUTE privileges to the routine creator. See
also Section 17.2.2, “Stored Routines and MySQL Privileges”. If binary
logging is enabled, the CREATE FUNCTION
statement might also require the SUPER
privilege, as described in
Section 17.5, “Binary Logging of Stored Programs”.
The DEFINER and SQL SECURITY
clauses specify the security context to be used when checking
access privileges at routine execution time, as described later.
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. Parameter names are not case
sensitive.
Each parameter can be declared to use any valid data type, except
that the COLLATE attribute cannot 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.
Specifying a parameter as IN,
OUT, or INOUT is valid
only for a PROCEDURE.
(FUNCTION parameters are always regarded as
IN parameters.)
An IN parameter passes a value into a
procedure. The procedure might modify the value, but the
modification is not visible to the caller when the procedure
returns. An OUT parameter passes a value from
the procedure back to the caller. Its initial value is
NULL within the procedure, and its value is
visible to the caller when the procedure returns. An
INOUT parameter is initialized by the caller,
can be modified by the procedure, and any change made by the
procedure is visible to the caller when the procedure returns.
For each OUT or INOUT
parameter, pass a user-defined variable so that you can obtain its
value when the procedure returns. (For an example, see
Section 12.2.1, “CALL Statement Syntax”.) If you are calling the procedure from
within another stored procedure or function, you can also pass a
routine parameter or local routine variable as an
IN or INOUT parameter.
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
statement. If the
valueRETURN statement returns a value of a different
type, the value is coerced to the proper type. For example, if a
function specifies an ENUM or
SET value in the RETURNS
clause, 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.
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 statements can contain
declarations, loops, and other control structure statements. The
syntax for these statements is described in
Section 12.8, “MySQL Compound-Statement Syntax”.
Some statements are not allowed in stored routines; see Section F.1, “Restrictions on Stored Routines and Triggers”.
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,
regardless of the current server SQL mode.
The CREATE FUNCTION statement is also used in
MySQL to support UDFs (user-defined functions). See
Section 20.2, “Adding New Functions to MySQL”. A UDF can be regarded as an
external stored function. However, do note that stored functions
share their namespace with UDFs. See
Section 8.2.3, “Function Name Parsing and Resolution”, for the rules describing
how the server interprets references to different kinds of
functions.
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.
A routine that contains the NOW()
function (or its synonyms) or
RAND() is non-deterministic, but
it might still be replication-safe. For
NOW(), the binary log includes the
timestamp and replicates correctly.
RAND() also replicates correctly
as long as it is invoked only once during the execution of a
routine. (You can consider the routine execution timestamp and
random number seed as implicit inputs that are identical on the
master and slave.)
Prior to MySQL 5.0.44, the DETERMINISTIC
characteristic is accepted, but not used by the optimizer.
However, if binary logging is enabled, this characteristic always
affects which routine definitions MySQL accepts. See
Section 17.5, “Binary Logging of Stored Programs”.
Several characteristics provide information about the nature of data use by the routine. In MySQL, these characteristics are advisory only. The server does not use them to constrain what kinds of statements a routine will be allowed to execute.
CONTAINS SQL indicates that the routine
does not contain statements that read or write data. This is
the default if none of these characteristics is given
explicitly. Examples of such statements are SET @x =
1 or DO RELEASE_LOCK('abc'),
which execute but neither read nor write data.
NO SQL indicates that the routine contains
no SQL statements.
READS SQL DATA indicates that the routine
contains statements that read data (for example,
SELECT), but not statements that write
data.
MODIFIES SQL DATA indicates that the
routine contains statements that may write data (for example,
INSERT or DELETE).
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. As of MySQL 5.0.3, 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.
The optional DEFINER clause specifies the MySQL
account to be used when checking access privileges at routine
execution time for routines that have the SQL SECURITY
DEFINER characteristic. The DEFINER
clause was added in MySQL 5.0.20.
If a user value is given for the
DEFINER clause, it should be a MySQL account in
'
format (the same format used in the user_name'@'host_name'GRANT
statement). The user_name and
host_name values both are required. The
definer can also be given as
CURRENT_USER or
CURRENT_USER(). The default
DEFINER value is the user who executes the
CREATE PROCEDURE or CREATE
FUNCTION or statement. (This is the same as
DEFINER = CURRENT_USER.)
If you specify the DEFINER clause, these rules
determine the legal DEFINER user values:
If you do not have the SUPER privilege, the
only legal user value is your own
account, either specified literally or by using
CURRENT_USER. You cannot set
the definer to some other account.
If you have the SUPER privilege, you can
specify any syntactically legal account name. If the account
does not actually exist, a warning is generated.
Although it is possible to create routines with a non-existent
DEFINER value, an error occurs if the
routine executes with definer privileges but the definer does
not exist at execution time.
As of MySQL 5.0.18, 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 12.8.3.1, “DECLARE for Local Variables”).
Assignments are checked for data type mismatches and overflow. Conversion and overflow problems result in warnings, or errors in strict mode.
Only scalar values can be assigned to parameters or variables.
For example, a statement such as SET x = (SELECT 1,
2) is invalid.
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, as of MySQL 5.0.25, the database character set
and collation that are in effect at the time the server loads
the routine into the routine cache are used. (These are given
by the values of the character_set_database
and collation_database system variables.)
If the database character set or collation change while the
routine is in the cache, routine execution is unaffected by
the change until the next time the server reloads the routine
into the cache. The COLLATE attribute is
not supported. (This includes use of
BINARY, because in this context
BINARY specifies the binary collation of
the character set.)
In MySQL 5.1, the database character set and collation in effect at the time the routine is created are used. Subsequent changes to the database character set or collation do not affect routine execution.
Before MySQL 5.0.18, parameters, return values, and local
variables are treated as items in expressions, and are subject to
automatic (silent) conversion and truncation. Stored functions
ignore the sql_mode setting.
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 perform 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.
Statements that return a result set cannot be used within a stored
function. This includes SELECT statements that
do not have an INTO
clause and other
statements such as var_listSHOW,
EXPLAIN, and CHECK TABLE.
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). 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).
Before MySQL 5.0.10, stored functions created with
CREATE FUNCTION must not contain references
to tables, with limited exceptions. They may include some
SET statements that contain table references,
for example SET a:= (SELECT MAX(id) FROM t),
and SELECT statements that fetch values
directly into variables, for example SELECT i INTO var1
FROM t.
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))mysql>RETURNS CHAR(50) DETERMINISTIC->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)
For information about invoking stored procedures from within
programs written in a language that has a MySQL interface, see
Section 12.2.1, “CALL Statement Syntax”.


User Comments
Calling stored procedures that return results using mysql_query will generate the following error unless the CLIENT_MULTI_RESULTS or CLIENT_MULTI_STATEMENTS flags have been set at connection time.
0x00000520 "PROCEDURE ... can't return a result set in the given context"
To export procedures with mysqldump use the --routines switch. However this does lead to a problem as the "delimiter" becomes ;; which leads to a problem on import. So here's a way to do it which I found in the forums, using sed to replace ;; with $$.
mysqldump <usual stuff here> --routines | sed -e "s/;;/\$\$/g" > myoutfile.sql
if you are using the Pear DB package you just need to add
'client_flags' => 65536
do your DSN array if you are getting: "can't retun a result set in the given context"
Add your own comment.