DELIMITER

DELIMITER cambia el carácter que MySQL usa para marcar el final de una sentencia. Por defecto es el punto y coma ;, pero al crear procedimientos almacenados necesitas cambiarlo porque el cuerpo del procedimiento contiene puntos y coma internos.

El problema

Sin cambiar el delimitador, MySQL interpreta el primer ; dentro del procedimiento como el final de la sentencia CREATE:

-- Esto FALLA porque MySQL corta en el primer ;
CREATE PROCEDURE test()
BEGIN
    SELECT 1;   -- MySQL piensa que aquí termina
    SELECT 2;
END;

La solución: DELIMITER

-- Cambiar el delimitador a //
DELIMITER //
 
CREATE PROCEDURE test()
BEGIN
    SELECT 1;   -- Ahora ; no termina la sentencia
    SELECT 2;
END //
 
-- Restaurar el delimitador original
DELIMITER ;

Delimitadores comunes

DelimitadorEjemplo
//Más común y legible
$$Muy popular, especialmente en PostgreSQL
;;Doble punto y coma

Puedes usar cualquier secuencia de caracteres que no aparezca en el cuerpo del procedimiento. // es la convención más habitual en MySQL.

Ejemplo práctico

DELIMITER //
 
CREATE PROCEDURE productos_por_categoria(IN cat_id INT)
BEGIN
    SELECT nombre, precio
    FROM productos
    WHERE categoria_id = cat_id
    ORDER BY precio DESC;
END //
 
DELIMITER ;
-- Llamar al procedimiento
CALL productos_por_categoria(6);
nombreprecio
iPhone 15 Pro1299.99
Samsung Galaxy S24899.99
Google Pixel 8699.00
Xiaomi 14599.99

Reglas importantes

  1. DELIMITER es un comando del cliente MySQL, no una sentencia SQL. No se puede usar dentro de un procedimiento.
  2. No dejes espacio entre DELIMITER y el nuevo delimitador en algunas interfaces. DELIMITER // es correcto.
  3. Siempre restaura el delimitador a ; después de crear el procedimiento.
  4. En herramientas como MySQL Workbench o phpMyAdmin, el delimitador puede configurarse de forma separada y a veces no es necesario cambiarlo manualmente.

Múltiples procedimientos

DELIMITER //
 
CREATE PROCEDURE proc_a()
BEGIN
    SELECT 'Procedimiento A';
END //
 
CREATE PROCEDURE proc_b()
BEGIN
    SELECT 'Procedimiento B';
END //
 
DELIMITER ;

Limpieza

DROP PROCEDURE IF EXISTS test;
DROP PROCEDURE IF EXISTS productos_por_categoria;
DROP PROCEDURE IF EXISTS proc_a;
DROP PROCEDURE IF EXISTS proc_b;

En el siguiente artículo veremos la sintaxis completa de CREATE PROCEDURE con todas sus opciones.

Escrito por Eduardo Lázaro