Procedimiento almacenado MySQL vs función, ¿qué usaría cuando?

160

Estoy mirando los procedimientos y la función almacenados de MySQL. ¿Cuál es la diferencia real?

Parecen ser similares, pero una función tiene más limitaciones.

Probablemente me equivoque, pero parece que un procedimiento almacenado puede hacer todo y más que una función almacenada. ¿Por qué / cuándo usaría un procedimiento frente a una función?

Seudónimo
fuente

Respuestas:

101

No puede mezclar procedimientos almacenados con SQL ordinario, mientras que con la función almacenada puede hacerlo.

por ejemplo, SELECT get_foo(myColumn) FROM mytableno es válido si get_foo()es un procedimiento, pero puede hacerlo si get_foo()es una función. El precio es que las funciones tienen más limitaciones que un procedimiento.

nos
fuente
18
¿Qué tipo de limitaciones tienen las funciones?
Fantius
11
Ah, he encontrado buena información aquí: dev.mysql.com/doc/refman/5.0/en/...
Fantius
262

La diferencia más general entre procedimientos y funciones es que se invocan de manera diferente y para diferentes propósitos:

  1. Un procedimiento no devuelve un valor. En su lugar, se invoca con una instrucción CALL para realizar una operación como modificar una tabla o procesar registros recuperados.
  2. Se invoca una función dentro de una expresión y devuelve un único valor directamente al llamador para que se use en la expresión.
  3. No puede invocar una función con una instrucción CALL, ni puede invocar un procedimiento en una expresión.

La sintaxis para la creación de rutina difiere un poco para los procedimientos y funciones:

  1. Los parámetros de procedimiento se pueden definir como solo de entrada, solo de salida o ambos. Esto significa que un procedimiento puede devolver valores a la persona que llama mediante el uso de parámetros de salida. Se puede acceder a estos valores en las declaraciones que siguen a la declaración CALL. Las funciones solo tienen parámetros de entrada. Como resultado, aunque tanto los procedimientos como las funciones pueden tener parámetros, la declaración de parámetros del procedimiento difiere de la de las funciones.
  2. Las funciones devuelven el valor, por lo que debe haber una cláusula RETURNS en una definición de función para indicar el tipo de datos del valor devuelto. Además, debe haber al menos una instrucción RETURN dentro del cuerpo de la función para devolver un valor a la persona que llama. DEVOLUCIONES y RETORNO no aparecen en las definiciones de procedimientos.

    • Para invocar un procedimiento almacenado, use el CALL statement. Para invocar una función almacenada, consúltela en una expresión. La función devuelve un valor durante la evaluación de la expresión.

    • Se invoca un procedimiento utilizando una instrucción CALL y solo puede transferir valores utilizando variables de salida. Se puede invocar una función desde dentro de una instrucción como cualquier otra función (es decir, invocando el nombre de la función), y puede devolver un valor escalar.

    • Especificar un parámetro como IN, OUT o INOUT solo es válido para un PROCEDIMIENTO. Para una FUNCIÓN, los parámetros siempre se consideran parámetros IN.

    Si no se proporciona una palabra clave antes del nombre de un parámetro, se trata de un parámetro IN por defecto. Los parámetros para las funciones almacenadas no están precedidos por IN, OUT o INOUT. Todos los parámetros de la función se tratan como parámetros IN.

Para definir un procedimiento o función almacenado, use CREATE PROCEDURE o CREATE FUNCTION respectivamente:

CREATE PROCEDURE proc_name ([parameters])
 [characteristics]
 routine_body


CREATE FUNCTION func_name ([parameters])
 RETURNS data_type       // diffrent
 [characteristics]
 routine_body

Una extensión de MySQL para el procedimiento almacenado (no las funciones) es que un procedimiento puede generar un conjunto de resultados, o incluso varios conjuntos de resultados, que la persona que llama procesa de la misma manera que el resultado de una instrucción SELECT. Sin embargo, el contenido de tales conjuntos de resultados no se puede usar directamente en la expresión.

Las rutinas almacenadas (que se refieren tanto a los procedimientos almacenados como a las funciones almacenadas) están asociadas a una base de datos particular, al igual que las tablas o vistas. Cuando descarta una base de datos, también se descartan las rutinas almacenadas en la base de datos.

Los procedimientos y funciones almacenados no comparten el mismo espacio de nombres. Es posible tener un procedimiento y una función con el mismo nombre en una base de datos.

En los procedimientos almacenados, se puede usar SQL dinámico, pero no en funciones o desencadenantes.

Las sentencias preparadas para SQL (PREPARAR, EJECUTAR, PREPARAR PREPARAR) se pueden usar en procedimientos almacenados, pero no en funciones o desencadenantes almacenados. Por lo tanto, las funciones y los desencadenantes almacenados no pueden usar SQL dinámico (donde construye sentencias como cadenas y luego las ejecuta). (SQL dinámico en rutinas almacenadas de MySQL)

Algunas diferencias más interesantes entre FUNCIÓN y PROCEDIMIENTO ALMACENADO:

  1. ( Este punto se copia de una publicación de blog ) . El procedimiento almacenado es un plan de ejecución precompilado donde las funciones no lo son. Función analizada y compilada en tiempo de ejecución. Procedimientos almacenados, almacenados como un pseudocódigo en la base de datos, es decir, en forma compilada.

  2. ( No estoy seguro de este punto ) .
    El procedimiento almacenado tiene la seguridad y reduce el tráfico de red y también podemos llamar al procedimiento almacenado en cualquier no. de aplicaciones a la vez. referencia

  3. Las funciones se usan normalmente para cálculos en los que los procedimientos se usan normalmente para ejecutar la lógica de negocios.

  4. Las funciones no pueden afectar el estado de la base de datos (las declaraciones que hacen commit o rollback explícito o implícito no están permitidas en la función) Mientras que los procedimientos almacenados pueden afectar el estado de la base de datos usando commit, etc.
    Referencia: J.1. Restricciones sobre rutinas almacenadas y disparadores

  5. Las funciones no pueden usar instrucciones FLUSH , mientras que los procedimientos almacenados sí.

  6. Las funciones almacenadas no pueden ser recursivas, mientras que los procedimientos almacenados sí pueden serlo. Nota: Los procedimientos almacenados recursivos están deshabilitados de manera predeterminada, pero pueden habilitarse en el servidor configurando la variable de sistema del servidor max_sp_recursion_depth en un valor distinto de cero. Consulte la Sección 5.2.3, “Variables del sistema” , para obtener más información.

  7. Dentro de una función o activador almacenado, no está permitido modificar una tabla que ya está siendo utilizada (para leer o escribir) por la instrucción que invocó la función o activador. Buen ejemplo: ¿Cómo actualizar la misma tabla de eliminación en MYSQL?

Nota : aunque algunas restricciones normalmente se aplican a funciones almacenadas y disparadores pero no a procedimientos almacenados, esas restricciones se aplican a procedimientos almacenados si se invocan desde una función almacenada o disparador. Por ejemplo, aunque puede usar FLUSH en un procedimiento almacenado, dicho procedimiento almacenado no se puede invocar desde una función almacenada o disparador.

Grijesh Chauhan
fuente
2
@GrijeshChauhan, ¿Qué quieres decir cuando dices que "Función analizada y compilada en tiempo de ejecución" ?
Pacerier
@Pacerier significa que las funciones en MySQL son algo así como scripts que compilan y ejecutan sobre la marcha. Lo copié de alguna publicación de blog , pero no realicé ninguna práctica para inspeccionar estos comportamientos.
Grijesh Chauhan
En los procedimientos, puede pasar una variable de salida como parámetro, luego llamarla con una instrucción select
LTroya
1
el punto # 4 en la sección inferior de esta respuesta es, creo, el núcleo de la diferencia entre procedimientos y funciones. los procedimientos pueden cambiar la base de datos, las funciones no. todas las otras diferencias son solo para servir a ese propósito de manera más efectiva.
Woodrow Barlow
51

Una diferencia significativa es que puede incluir una función en sus consultas SQL, pero los procedimientos almacenados solo pueden invocarse con la CALLdeclaración:

Ejemplo UDF:

CREATE FUNCTION hello (s CHAR(20))
   RETURNS CHAR(50) DETERMINISTIC
   RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');

SELECT hello(name) FROM names;
+--------------+
| hello(name)  |
+--------------+
| Hello, Bob!  |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)

Ejemplo de Sproc:

delimiter //

CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
   SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)

delimiter ;

CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World!             |
+---------------------------+
1 row in set (0.00 sec)
Daniel Vassallo
fuente
1
¿Tu función tiene dos retornos ? Quiero decir, ¿qué es esta línea? RETURNS CHAR(50) DETERMINISTIC?
Martin AJ
Las RETURNS CHAR(50)serán devueltos estados qué tipo de datos. El RETURN CONCAT(...es la información que se devuelve. Ambos son necesarios. Se DETERMINISTICnecesita para indicar que los datos subyacentes no se modificarán.
lemming622
8

Una función almacenada se puede usar dentro de una consulta. Luego puede aplicarlo a cada fila, o dentro de una cláusula WHERE.

Un procedimiento se ejecuta utilizando la consulta CALL.

Evert
fuente
0

El procedimiento almacenado se puede llamar de forma recursiva pero la función almacenada no se puede

palash140
fuente