Procedimientos almacenados y las tablas de permisos
Los procedimientos almacenados requieren la tabla
proc
en la base de datos mysql
. Esta tabla se crea durante la isntalación de MySQL 5.0. Si está actualizando a MySQL 5.0 desde una versión anterior, asegúrese de actualizar sus tablas de permisos para asegurar que la tabla proc
existe. Consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.
Desde MySQL 5.0.3, el sistema de permisos se ha modificado para tener en cuenta los procedimientos almacenados como sigue:
- El permiso
CREATE ROUTINE
se necesita para crear procedimientos almacenados. - El permiso
ALTER ROUTINE
se necesita para alterar o borrar procedimientos almacenados. Este permiso se da automáticamente al creador de una rutina. - El permiso
EXECUTE
se requiere para ejectuar procedimientos almacenados. Sin embargo, este permiso se da automáticamente al creador de la rutina. También, la característicaSQL SECURITY
por defecto para una rutina esDEFINER
, lo que permite a los usuarios que tienen acceso a la base de datos ejecutar la rutina asociada.
Los procedimientos almacenados y rutinas se crean con comandos
CREATE PROCEDURE
y CREATE FUNCTION
. Una rutina es un procedimiento o una función. Un procedimiento se invoca usando un comando CALL
, y sólo puede pasar valores usando variables de salida. Una función puede llamarse desde dentro de un comando como cualquier otra función (esto es, invocando el nombre de la función), y puede retornar un valor escalar. Las rutinas almacenadas pueden llamar otras rutinas almacenadas.
Desde MySQL 5.0.1, los procedimientos almacenadoso funciones se asocian con una base de datos. Esto tiene varias implicaciones:
- Cunado se invoca la rutina, se realiza implícitamente
USE
( y se deshace cuando acaba la rutina). Los comandosdb_name
USE
dentro de procedimientos almacenados no se permiten. - Puede calificar los nombres de rutina con el nombre de la base de datos. Esto puede usarse para referirse a una rutina que no esté en la base de datos actual. Por ejemplo, para invocar procedimientos almacenados
p
o funcionesf
esto se asocia con la base de datostest
, puede decirCALL test.p()
otest.f()
. - Cuando se borra una base de datos, todos los procedimientos almacenados asociados con ella también se borran.
(En MySQL 5.0.0, los procedimientos almacenados son globales y no asociados con una base de datos. Heredan la base de datos por defecto del llamador. Si se ejecuta
USE db_name
desde la rutina, la base de datos por defecto original se restaura a la salida de la rutina.)
MySQL soporta la extensión muy útil que permite el uso de comandos regulares
SELECT
(esto es, sin usar cursores o variables locales) dentro de los procedimientos almacenados. El conjunto de resultados de estas consultas se envía diractamente al cliente. Comandos SELECT
múltiples generan varios conjuntos de resultados, así que el cliente debe usar una biblioteca cliente de MySQL que soporte conjuntos de resultados múltiples. Esto significa que el cliente debe usar una biblioteca cliente de MySQL como mínimos desde 4.1.
La siguiente sección describe la sintaxis usada para crear, alterar, borrar, y consultar procedimientos almacenados y funciones.
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.Enlace a información:
https://manuales.guebs.com/mysql-5.0/stored-procedures.html#variables-in-stored-procedures
No hay comentarios:
Publicar un comentario