Parte 1
Os delimitadores são usados para objetos de origem como procedimento/função armazenado, gatilho ou evento. Todos esses objetos podem ter um corpo - código dentro da cláusula BEGIN...END.
Todas as instruções em scripts MySQL devem ser finalizadas com delimitador, o padrão é ';'. Mas o que fazer se o objeto de origem tiver corpo com algumas instruções, por exemplo:
INSERT INTO table1 VALUES(1);
CREATE PROCEDURE procedure1()
BEGIN
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @a = 6;
SET @b = 8;
EXECUTE stmt2 USING @a, @b;
END;
INSERT INTO table1 VALUES(2);
Quantos enunciados? 3 ou 8? A resposta é três, porque o script tem dois comandos INSERTs e um CREATE PROCEDURE. Como você vê, CREATE PROCEDURE também possui algumas instruções internas; devemos dizer ao cliente MySQL que todas essas declarações (dentro de BEGIN...END) - fazem parte de UMA declaração; podemos fazer isso com a ajuda de delimitadores:
INSERT INTO table1 VALUES(1);
DELIMITER $$
CREATE PROCEDURE procedure1()
BEGIN
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @a = 6;
SET @b = 8;
EXECUTE stmt2 USING @a, @b;
END$$
DELIMITER ;
INSERT INTO table1 VALUES(2);
Observe que, quando seu gatilho não tem uma cláusula BEGIN...END, os delimitadores podem ser omitidos.
Parte 2
Sem delimitadores, a instrução será analisada como -
CREATE PROCEDURE procedure1()
BEGIN
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
ao invés de -
CREATE PROCEDURE procedure1()
BEGIN
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @a = 6;
SET @b = 8;
EXECUTE stmt2 USING @a, @b;
END