ALTER PROCEDURE
ALTER PROCEDURE modifica las características de un procedimiento almacenado existente. No puede modificar el cuerpo ni los parámetros del procedimiento; para eso necesitas eliminarlo y recrearlo.
Es un comando con alcance limitado que muchos desarrolladores ni siquiera conocen, ya que el patrón habitual para modificar un procedimiento es DROP + CREATE. Sin embargo, ALTER PROCEDURE tiene su utilidad: permite cambiar metadatos y comportamiento del procedimiento sin necesidad de tener el código fuente completo a mano ni perder los permisos EXECUTE asociados.
Sintaxis
ALTER PROCEDURE nombre_procedimiento
[COMMENT 'texto']
[LANGUAGE SQL]
[{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }]
[SQL SECURITY { DEFINER | INVOKER }]Qué puede cambiar ALTER PROCEDURE
| Característica | Descripción |
|---|---|
| COMMENT | Texto descriptivo del procedimiento |
| SQL SECURITY | DEFINER o INVOKER |
| Característica SQL | CONTAINS SQL, NO SQL, READS SQL DATA, MODIFIES SQL DATA |
Qué NO puede cambiar
ALTER PROCEDURE no puede modificar tres aspectos fundamentales:
- El cuerpo del procedimiento (las sentencias SQL entre BEGIN y END)
- Los parámetros (ni añadir, ni quitar, ni cambiar tipos)
- El nombre (MySQL no tiene RENAME PROCEDURE)
Para cambiar cualquiera de estos tres, la única opción es eliminar el procedimiento con DROP y recrearlo con CREATE. Esta es una limitación histórica de MySQL que contrasta con otros motores como Oracle o SQL Server, que ofrecen CREATE OR REPLACE PROCEDURE.
Cambiar el comentario
El caso de uso más práctico de ALTER PROCEDURE es añadir o actualizar la documentación del procedimiento sin tocar su código:
DELIMITER //
CREATE PROCEDURE sp_ejemplo()
BEGIN
SELECT COUNT(*) AS total FROM productos;
END //
DELIMITER ;-- Añadir un comentario
ALTER PROCEDURE sp_ejemplo
COMMENT 'Cuenta el total de productos en la base de datos';-- Verificar el cambio
SELECT ROUTINE_NAME, ROUTINE_COMMENT
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = 'tienda_mysql'
AND ROUTINE_NAME = 'sp_ejemplo';| ROUTINE_NAME | ROUTINE_COMMENT |
|---|---|
| sp_ejemplo | Cuenta el total de productos en la base de datos |
Documentar procedimientos con COMMENT es especialmente valioso en bases de datos con decenas de procedimientos, donde el nombre por sí solo no siempre comunica qué hace cada uno. Herramientas de administración como MySQL Workbench muestran estos comentarios al listar procedimientos, facilitando la navegación.
Cambiar SQL SECURITY
Cambiar el modo de seguridad es probablemente el uso más importante de ALTER PROCEDURE en entornos de producción. Permite ajustar los permisos sin necesidad de eliminar y recrear el procedimiento (lo que haría perder los GRANT EXECUTE asociados):
-- Crear procedimiento con DEFINER (por defecto)
DELIMITER //
CREATE PROCEDURE sp_ver_precios()
SQL SECURITY DEFINER
BEGIN
SELECT nombre, precio FROM productos WHERE activo = TRUE;
END //
DELIMITER ;-- Cambiar a INVOKER
ALTER PROCEDURE sp_ver_precios
SQL SECURITY INVOKER;| Modo | Comportamiento |
|---|---|
| DEFINER | Se ejecuta con los permisos del usuario que creó el procedimiento |
| INVOKER | Se ejecuta con los permisos del usuario que llama al procedimiento |
Cambiar de DEFINER a INVOKER es útil cuando quieres que el procedimiento respete los permisos del usuario que lo llama, por ejemplo, si diferentes usuarios deben ver diferentes datos según sus privilegios. Cambiar de INVOKER a DEFINER es útil cuando quieres dar acceso controlado a datos que el usuario normalmente no podría consultar. Para una explicación detallada del modelo de seguridad, consulta el artículo de control de acceso.
Cambiar característica SQL
Las características SQL describen qué tipo de operaciones realiza el procedimiento. Aunque MySQL no las verifica activamente (no te impedirá ejecutar un INSERT en un procedimiento marcado como READS SQL DATA), sí pueden afectar a la replicación y a optimizaciones internas:
-- Indicar que el procedimiento solo lee datos
ALTER PROCEDURE sp_ver_precios
READS SQL DATA
COMMENT 'Lista precios de productos activos';| Característica | Significado |
|---|---|
| CONTAINS SQL | Contiene sentencias SQL pero no lee ni modifica datos (por defecto) |
| NO SQL | No contiene sentencias SQL |
| READS SQL DATA | Solo lee datos con SELECT |
| MODIFIES SQL DATA | Puede modificar datos con INSERT, UPDATE, DELETE |
En la práctica, estas características son informativas: sirven para documentar la intención del procedimiento y pueden ser consultadas por herramientas de análisis. Sin embargo, en entornos con replicación basada en sentencias (statement-based replication), MySQL puede usar estas características para tomar decisiones sobre cómo replicar las llamadas al procedimiento.
Múltiples cambios a la vez
Puedes modificar varias características en una sola sentencia ALTER:
ALTER PROCEDURE sp_ver_precios
SQL SECURITY INVOKER
READS SQL DATA
COMMENT 'Procedimiento público para consultar precios';Esto es más eficiente que ejecutar tres ALTER PROCEDURE separados y garantiza que los cambios se apliquen de forma atómica.
Patrón para modificar el cuerpo
Como ALTER PROCEDURE no puede cambiar el cuerpo, el patrón estándar para actualizaciones completas es DROP + CREATE:
-- 1. Guardar la definición actual (por seguridad)
SHOW CREATE PROCEDURE sp_ver_precios\G
-- 2. Eliminar
DROP PROCEDURE IF EXISTS sp_ver_precios;
-- 3. Recrear con los cambios
DELIMITER //
CREATE PROCEDURE sp_ver_precios()
SQL SECURITY INVOKER
READS SQL DATA
COMMENT 'Lista precios de productos activos con stock'
BEGIN
SELECT nombre, precio, stock
FROM productos
WHERE activo = TRUE AND stock > 0
ORDER BY precio;
END //
DELIMITER ;El paso 1 (guardar la definición) es importante como red de seguridad: si el nuevo CREATE falla por un error de sintaxis, no pierdes la definición anterior. En un flujo de trabajo con control de versiones, este paso no es tan necesario porque siempre puedes recuperar la versión anterior del repositorio.
La desventaja del DROP + CREATE es que los permisos EXECUTE se pierden con el DROP. Si el procedimiento tenía GRANT EXECUTE para varios usuarios, deberás volver a otorgarlos después del CREATE. Por eso, para cambios que solo afectan a las características (no al cuerpo), ALTER PROCEDURE es la opción preferible.
Permisos necesarios
Para usar ALTER PROCEDURE necesitas:
- Privilegio
ALTER ROUTINEen el procedimiento, o - Ser el DEFINER del procedimiento
-- Verificar el DEFINER de un procedimiento
SELECT ROUTINE_NAME, DEFINER
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = 'tienda_mysql'
AND ROUTINE_TYPE = 'PROCEDURE';Si no eres el DEFINER y no tienes ALTER ROUTINE, la sentencia fallará con un error de permisos.
Limpieza
DROP PROCEDURE IF EXISTS sp_ejemplo;
DROP PROCEDURE IF EXISTS sp_ver_precios;En el siguiente artículo veremos el control de acceso en procedimientos almacenados y cómo gestionar permisos.
Escrito por Eduardo Lázaro
