CREATE PROCEDUREsp_name
([parameter
[,...]]) [characteristic
...]routine_body
CREATE FUNCTIONsp_name
([parameter
[,...]]) RETURNStype
[characteristic
...]routine_body
parameter
: [ IN | OUT | INOUT ]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
:procedimientos almacenados o comandos SQL válidos
Estos comandos crean una rutina almacenada. Desde MySQL 5.0.3,
para crear una rutina, es necesario tener el permiso
CREATE ROUTINE
, y los permisos
ALTER ROUTINE
y EXECUTE
se
asignan automáticamente a su creador. Si se permite logueo
binario necesita también el permisos SUPER
como se describe en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.
Por defecto, la rutina se asocia con la base de datos actual.
Para asociar la rutina explícitamente con una base de datos,
especifique el nombre como
db_name.sp_name
al crearlo.
Si el nombre de rutina es el mismo que el nombre de una función de SQL, necesita usar un espacio entre el nombre y el siguiente paréntesis al definir la rutina, o hay un error de sintaxis. Esto también es cierto cuando invoca la rutina posteriormente.
La cláusula RETURNS
puede especificarse
sólo con FUNCTION
, donde es obligatorio. Se
usa para indicar el tipo de retorno de la función, y el cuerpo
de la función debe contener un comando RETURN
value
.
La lista de parámetros entre paréntesis debe estar siempre
presente. Si no hay parámetros, se debe usar una lista de
parámetros vacía ()
. Cada parámetro es un
parámetro IN
por defecto. Para especificar
otro tipo de parámetro, use la palabra clave
OUT
o INOUT
antes del
nombre del parámetro. Especificando IN
,
OUT
, o INOUT
sólo es
valido para una PROCEDURE
.
El comando CREATE FUNCTION
se usa en
versiones anteriores de MySQL para soportar UDFs (User Defined
Functions) (Funciones Definidas por el Usuario). Consulte
Sección 27.2, “Añadir nuevas funciones a MySQL”. UDFs se soportan, incluso
con la existencia de procedimientos almacenados. Un UDF puede
tratarse como una función almacenada externa. Sin embargo,
tenga en cuenta que los procedimientos almacenados comparten su
espacio de nombres con UDFs.
Un marco para procedimientos almacenados externos se introducirá en el futuro. Esto permitira escribir procedimientos almacenados en lenguajes distintos a SQL. Uno de los primeros lenguajes a soportar será PHP ya que el motor central de PHP es pequeño, con flujos seguros y puede empotrarse fácilmente. Como el marco es público, se espera soportar muchos otros lenguajes.
Un procedimiento o función se considera
“determinista” si siempre produce el mismo
resultado para los mismos parámetros de entrada, y “no
determinista” en cualquier otro caso. Si no se da ni
DETERMINISTIC
ni NOT
DETERMINISTIC
por defecto es NOT
DETERMINISTIC
.
Para replicación, use la función NOW()
(o
su sinónimo) o RAND()
no hace una rutina no
determinista necesariamente. Para NOW()
, el
log binario incluye el tiempo y hora y replica correctamente.
RAND()
también replica correctamente
mientras se invoque sólo una vez dentro de una rutina. (Puede
considerar el tiempo y hora de ejecución de la rutina y una
semilla de número aleatorio como entradas implícitas que son
idénticas en el maestro y el esclavo.)
Actualmente, la característica DETERMINISTIC
se acepta, pero no la usa el optimizador. Sin embargo, si se
permite el logueo binario, esta característica afecta si MySQL
acepta definición de rutinas. Consulte
Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.
Varias características proporcionan información sobre la
naturaleza de los datos usados por la rutina. CONTAINS
SQL
indica que la rutina no contiene comandos que leen
o escriben datos. NO SQL
indica que la rutina
no contiene comandos SQL . READS SQL DATA
indica que la rutina contiene comandos que leen datos, pero no
comandos que escriben datos. MODIFIES SQL
DATA
indica que la rutina contiene comandos que pueden
escribir datos. CONTAINS SQL
es el valor por
defecto si no se dan explícitamente ninguna de estas
características.
La característica SQL SECURITY
puede usarse
para especificar si la rutina debe ser ejecutada usando los
permisos del usuario que crea la rutina o el usuario que la
invoca. El valor por defecto es DEFINER
. Esta
característica es nueva en SQL:2003. El creador o el invocador
deben tener permisos para acceder a la base de datos con la que
la rutina está asociada. Desde MySQL 5.0.3, es necesario tener
el permiso EXECUTE
para ser capaz de ejecutar
la rutina. El usuario que debe tener este permiso es el
definidor o el invocador, en función de cómo la
característica SQL SECURITY
.
MySQL almacena la variable de sistema
sql_mode
que está en efecto cuando se crea
la rutina, y siempre ejecuta la rutina con esta inicialización.
La cláusula COMMENT
es una extensión de
MySQL, y puede usarse para describir el procedimiento
almacenado. Esta información se muestra con los comandos
SHOW CREATE PROCEDURE
y SHOW CREATE
FUNCTION
.
MySQL permite a las rutinas que contengan comandos DDL (tales
como CREATE
y DROP
) y
comandos de transacción SQL (como COMMIT
).
Esto no lo requiere el estándar, y por lo tanto, es específico
de la implementación.
Los procedimientos almacenados no pueden usar LOAD DATA
INFILE
.
Nota: Actualmente, los
procedimientos almacenados creados con CREATE
FUNCTION
no pueden tener referencias a tablas. (Esto
puede incluir algunos comandos SET
que pueden
contener referencias a tablas, por ejemplo SET a:=
(SELECT MAX(id) FROM t)
, y por otra parte no pueden
contener comandos SELECT
, por ejemplo
SELECT 'Hello world!' INTO var1
.) Esta
limitación se elminará en breve.
Los comandos que retornan un conjunto de resultados no pueden
usarse desde una función almacenada. Esto incluye comandos
SELECT
que no usan INTO
para tratar valores de columnas en variables, comandos
SHOW
y otros comandos como
EXPLAIN
. Para comandos que pueden
determinarse al definir la función para que retornen un
conjunto de resultados, aparece un mensaje de error Not
allowed to return a result set from a function
(ER_SP_NO_RETSET_IN_FUNC
). Para comandos que
puede determinarse sólo en tiempo de ejecución si retornan un
conjunto de resultados, aparece el error PROCEDURE %s
can't return a result set in the given context
(ER_SP_BADSELECT
).
El siguiente es un ejemplo de un procedimiento almacenado que
use un parámetro OUT
. El ejemplo usa el
cliente mysql y el comando
delimiter
para cambiar el delimitador del
comando de ;
a //
mientras
se define el procedimiento . Esto permite pasar el delimitador
;
usado en el cuerpo del procedimiento a
través del servidor en lugar de ser interpretado por el mismo
mysql.
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)
Al usar el comando delimiter
, debe evitar el
uso de la antibarra ('\
') ya que es el
carácter de escape de MySQL.
El siguiente es un ejemplo de función que toma un parámetro, realiza una operación con una función SQL, y retorna el resultado:
mysql> delimiter // mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) -> RETURN CONCAT('Hello, ',s,'!'); -> // Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; mysql> SELECT hello('world'); +----------------+ | hello('world') | +----------------+ | Hello, world! | +----------------+ 1 row in set (0.00 sec)
Si el comando RETURN
en un procedimiento
almacenado retorna un valor con un tipo distinto al especificado
en la cláusula RETURNS
de la función, el
valor de retorno se coherciona al tipo apropiado. Por ejemplo,
si una función retorna un valor ENUM
o
SET
, pero el comando
RETURN
retorna un entero, el valor retornado
por la función es la cadena para el miembro de
ENUM
correspondiente de un conjunto de
miembros SET
.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.