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. 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 18.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 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.
Note: 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 18.2.4, “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
statement syntax is described in Section 18.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 18.2.6, “DECLARE Statement Syntax”, and
Section 18.2.10, “Flow Control Constructs”. Some statements are
not allowed in stored routines; see
Section D.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 was used in
earlier versions of MySQL to support UDFs (user-defined
functions). See Section 26.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. See Section 9.2.4, “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 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 18.4, “Binary Logging of Stored Routines and Triggers”.
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. 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.1.8.
If a user value is given, 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.
CURRENT_USER also can be given as
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, you cannot
set the value to any account but your own unless you have the
SUPER privilege. 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.
When the routine is invoked, an implicit USE
is performed (and
undone when the routine terminates). db_nameUSE
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 18.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
that are in effect at the time the routine is created are
used. (These are given by the values of the
character_set_database and
collation_database system variables.) The
COLLATE attribute is not supported. (This
includes use of BINARY, because in this
context BINARY specifies the binary
collation of the character set.)
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)
For information about invoking stored procedures from within
programs written in a language that has a MySQL interface, see
Section 18.2.4, “CALL Statement Syntax”.

User Comments
Here are my functions for extracting the domain and subdomain from a URL:
mysql> CREATE FUNCTION domain_of_url (url TEXT) RETURNS varchar(255) RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING "https://" FROM TRIM(LEADING "http://" FROM TRIM(url))), "/", 1), ":", 1), ".", if(url LIKE "%.org.__%" OR url LIKE "%.net.__%" OR url LIKE "%.com.__%" OR url LIKE "%.__.us%" OR url LIKE "%.co.__%" OR url LIKE "%.__.uk%", -3, -2) );
mysql> SELECT domain_of_url(" http://www.richardkmiller.com:80/blog/ ") AS domain;
mysql> CREATE FUNCTION subdomain_of_url (url TEXT) RETURNS varchar(255) RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(LEADING "https://" FROM TRIM(LEADING "http://" FROM TRIM(url))), "/", 1), ":", 1);
mysql> SELECT subdomain_of_url(" http://www.richardkmiller.com:80/blog/ ") AS subdomain;
To see which procedures are installed you can use:
SELECT type,db,name,param_list FROM mysql.proc;
I have not found a SHOW PROCEDURE or similar command, but this works as well.
/Klas
To see which procedures are installed I recommend to use SHOW PROCEDURE STATUS and SHOW FUNCTION STATUS. See Section 13.5.4.23, “SHOW PROCEDURE STATUS and SHOW FUNCTION STATUS Syntax”.
You can also get information about stored routines from the ROUTINES table in INFORMATION_SCHEMA. See Section 24.14, “The INFORMATION_SCHEMA ROUTINES Table”.
To show what the delimiter is set to, use the status command. For example, if you want to verify that the delimiter is set to //, then:
mysql> status //
The "Using delimiter:" row in the output will show what the delimiter is set to.
Just adding to the tip above, you can also supply a parameter just like show table status:
show procedure status like 'foo';
I rustled up a stored procedure (SP) that quickly lets me query the database based on a key pasted in from a web page. The web page formats the key for prettiness and the database stores it in a compact form.
eg. on the web page the key is 4 groups of 4 chars like this: ABCD EFGH IJKL MNOP
in the database they are stored as ABCDEFGHIJKLMNOP
I like to copy and paste from the webpage so there is some tedious deletes on the spaces to enable them to match. Here a SP comes to the rescue:
create procedure keyinfo (IN webpage_key VARCHAR(32))
begin
declare trimmed_key CHAR(16);
select replace(webpage_key, ' ','') into trimmed_key;
select * from key_table where the_key = trimmed_key;
end
Voila!
You can call the SP with \G for nice vertical output.
In reference to Darl Kuhn's suggestion for using the status command to determine the delimiter...
You don't need to write anything after "status", including a delimiter. So, in his example, you don't need the trailing "//" even if that is the delimiter. You can just type status and press enter.
This is fortunate, because status is the best way to determine the delimiter directly without resorting to trial and error - so if the status command itself required a delimiter, that would be a Catch 22.
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
Besides SHOW FUNCTION|PROCEDURE STATUS, you might also want to use:
SELECT SPECIFIC_NAME,ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES\G
or
SHOW CREATE FUNCTION|PROCEDURE routine_name\G
depending on what information you are looking for.
Add your own comment.