web-dev-qa-db-fra.com

Comment générer une erreur dans une fonction MySQL

J'ai créé une fonction MySQL et je voudrais générer une erreur si les valeurs transmises pour les paramètres ne sont pas valides. Quelles sont mes options pour déclencher une erreur dans une fonction MySQL?

61
Dónal

MySQL 5.5 introduit des signaux, qui sont similaires aux exceptions dans d'autres langues:

http://dev.mysql.com/doc/refman/5.5/en/signal.html

Par exemple, dans le client de ligne de commande mysql:

mysql> SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Custom error';
ERROR 1644 (45000): Custom error
73
Austin Hyde

Il s'agit en fait d'une combinaison des trois réponses. Vous appelez une procédure inexistante pour déclencher l'erreur, puis déclarez un gestionnaire de sortie qui intercepte l'erreur que vous avez générée. Voici un exemple, en utilisant SQLSTATE 42000 (la procédure n'existe pas) pour générer une erreur avant la suppression si la ligne à supprimer a un ID de clé étrangère défini:

DROP PROCEDURE IF EXISTS decount_test;

DELIMITER //

CREATE DEFINER = 'root'@'localhost' PROCEDURE decount_test ( p_id bigint )
DETERMINISTIC MODIFIES SQL DATA
BEGIN
  DECLARE EXIT HANDLER FOR SQLSTATE '42000'
    SELECT 'Invoiced barcodes may not have accounting removed.';
  IF (SELECT invoice_id 
       FROM accounted_barcodes
       WHERE id = p_id
    ) THEN
    CALL raise_error;
 END IF;
 DELETE FROM accounted_barcodes WHERE id = p_id;
END //

DELIMITER ;

Sortie:

call decount_test(123456);
+----------------------------------------------------+
| Invoiced barcodes may not have accounting removed. |
+----------------------------------------------------+
| Invoiced barcodes may not have accounting removed. | 
+----------------------------------------------------+
25
Ryan M

Pourquoi ne pas simplement stocker un VARCHAR dans une variable déclarée INTEGER?

DELIMITER $$ DROP FUNCTION IF EXISTS `raise_error` $$
CREATE FUNCTION `raise_error`(MESSAGE VARCHAR(255)) 
RETURNS INTEGER DETERMINISTIC BEGIN
  DECLARE ERROR INTEGER;
  set ERROR := MESSAGE;
  RETURN 0;
END $$ DELIMITER ;
-- set @foo := raise_error('something failed'); -- or within a query

Le message d'erreur est:

Valeur entière incorrecte: "quelque chose a échoué" pour la colonne "ERREUR" à la ligne 1

Ce n'est pas parfait, mais il donne un message assez descriptif et vous n'avez pas besoin d'écrire de DLL d'extension.

8
user645280

Dans MySQL 5, vous pouvez déclencher une erreur en appelant une procédure stockée qui n'existe pas (CALL raise_error) ou en transmettant une valeur non valide à une requête (comme null à un champ contraint NOT NULL). Voici un article intéressant de Roland Bouman sur la génération d'erreurs à partir d'une fonction MySQL:

http://rpbouman.blogspot.com/2005/11/using-udf-to-raise-errors-from-inside.html

5
Patrick de Kleijn

Vous pouvez également appeler une fonction existante avec un nombre d'arguments non valide.

2
Andrew Charneski

Vous devez définir des gestionnaires d'exceptions. Jetez un œil à http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html

0
Jorge Niedbalski R.