FirebirdSQL logo

Exemples d’utilisation WHEN…​DO

Example 1. Remplacer une erreur standard par la vôtre.
CREATE EXCEPTION COUNTRY_EXIST '';
SET TERM ^;
CREATE PROCEDURE ADD_COUNTRY (
    ACountryName COUNTRYNAME,
    ACurrency VARCHAR(10) )
AS
BEGIN
  INSERT INTO country (country, currency)
  VALUES (:ACountryName, :ACurrency);

  WHEN SQLCODE -803 DO
    EXCEPTION COUNTRY_EXIST 'Un tel pays a déjà été ajouté !';
END^
SET TERM ^;
Example 2. Enregistrez l’erreur dans le journal et ré-exécutez-la dans le bloc WHEN.
CREATE PROCEDURE ADD_COUNTRY (
    ACountryName COUNTRYNAME,
    ACurrency VARCHAR(10) )
AS
BEGIN
  INSERT INTO country (country,
                       currency)
  VALUES (:ACountryName,
          :ACurrency);
  WHEN ANY DO
  BEGIN
    -- Enregistrement de l'erreur
    IN AUTONOMOUS TRANSACTION DO
      INSERT INTO ERROR_LOG (PSQL_MODULE,
                             ERROR_TEXT,
                             EXCEPTION_NAME,
                             GDS_CODE,
                             SQL_CODE,
                             SQL_STATE)
      VALUES ('ADD_COUNTRY',
              RDB$ERROR(MESSAGE), -- texte du message d'erreur
              RDB$ERROR(EXCEPTION), -- le nom de l'exception de l'utilisateur
              GDSCODE,
              SQLCODE,
              SQLSTATE
      );
    -- Relancer l'erreur
    EXCEPTION;
  END
END
Example 3. Traitement en une seule fois WHEN …​ DO d’un bloc de plusieurs erreurs
...
WHEN GDSCODE GRANT_OBJ_NOTFOUND,
	   GDSCODE GRANT_FLD_NOTFOUND,
	   GDSCODE GRANT_NOPRIV,
	   GDSCODE GRANT_NOPRIV_ON_BASE
DO
BEGIN
	EXECUTE PROCEDURE LOG_GRANT_ERROR(GDSCODE);
	EXIT;
END
...
Example 4. Interception des erreurs par le code SQLSTATE.
EXECUTE BLOCK
AS
    DECLARE VARIABLE I INT;
BEGIN
  BEGIN
    I = 1 / 0;
    WHEN SQLSTATE '22003' DO
      EXCEPTION E_CUSTOM_EXCEPTION
        'Numeric value out of range.';
    WHEN SQLSTATE '22012' DO
      EXCEPTION E_CUSTOM_EXCEPTION 'Division by zero.';
    WHEN SQLSTATE '23000' DO
      EXCEPTION E_CUSTOM_EXCEPTION
        'Integrity constraint violation.';
  END
END

DECLARE …​ CURSOR

Destination:

Annonce du curseur.

Disponible en:

PSQL

Syntaxe
DECLARE [VARIABLE] cursor_name
  [SCROLL | NO SCROLL]
  CURSOR FOR (<select_statement>);
Table 1. Paramètres de l’instruction DECLARE …​ CURSOR
Paramètre Description

cursor_name

Nom du curseur.

select_statement

Instruction SELECT.

La commande DECLARE …​ CURSOR FOR déclare un curseur nommé, le liant au jeu de données obtenu dans l’instruction SELECT spécifiée dans la clause CURSOR FOR. Le curseur peut alors être ouvert, utilisé pour contourner le jeu de données résultant, et être refermé. Les mises à jour et suppressions positionnées sont également supportées en utilisant WHERE CURRENT OF dans les instructions UPDATE et DELETE.

Le nom du curseur peut être utilisé comme référence au curseur en tant que variable de type d’enregistrement. L’enregistrement courant est accessible via le nom du curseur, ce qui rend inutile la clause INTO dans l’instruction FETCH.

Curseurs unidirectionnels et de défilement

Les curseurs peuvent être défilables unidirectionnellement. La clause optionnelle SCROLL rend le curseur bidirectionnel (défilable), la clause NO SCROLL le rend unidirectionnel. Par défaut, les curseurs sont unidirectionnels.

Les curseurs unidirectionnels permettent uniquement un déplacement vers l’avant dans un ensemble de données, tandis que les curseurs bidirectionnels permettent non seulement un déplacement vers l’avant mais aussi vers l’arrière dans un ensemble de données et N positions par rapport à la position actuelle.

Warning

Les curseurs défilants se matérialisent en interne comme un jeu de données temporaire, ils consomment donc des ressources mémoire/disque supplémentaires, aussi ne les utilisez que lorsque cela est vraiment nécessaire.

Caractéristiques de l’utilisation du curseur

  • La clause FOR UPDATE est autorisée dans l’instruction SELECT, mais elle n’est pas nécessaire pour une mise à jour ou une suppression positionnelle réussie ;

  • Assurez-vous que les noms de curseurs déclarés ne correspondent pas à des noms définis plus tard dans les clauses AS CURSOR ;

  • Si un curseur n’est nécessaire que pour parcourir le jeu de données résultant, il est presque toujours plus facile (et moins sujet aux erreurs) d’utiliser l’instruction FOR SELECT avec la clause AS CURSOR. Les curseurs déclarés doivent être explicitement ouverts, utilisés pour sélectionner des données et fermés. Vous devez également vérifier la variable contextuelle ROW_COUNT après chaque sélection et quitter la boucle si sa valeur est nulle. La clause FOR SELECT effectue cette vérification automatiquement. Cependant, les curseurs déclarés donnent un meilleur contrôle sur les événements séquentiels et permettent de gérer plusieurs curseurs en parallèle ;

  • L’instruction SELECT peut contenir des paramètres tels que : "SÉLECTIONNER NOM || :SFX À PARTIR DE NOMS OÙ NUMÉRO = :NUM". Chaque paramètre doit être déclaré au préalable comme une variable PSQL (ceci s’applique également aux paramètres d’entrée et de sortie). Lorsque le curseur est ouvert, le paramètre se voit attribuer la valeur variable actuelle ;

  • Si l’option de défilement est omise, NO SCROLL est supposé par défaut (c’est-à-dire que le curseur n’est ouvert que pour un déplacement vers l’avant). Cela signifie que seules les commandes FETCH [NEXT FROM] peuvent être utilisées. Les autres commandes renverront des erreurs.

Warning

Si la valeur d’une variable PSQL utilisée dans une instruction SELECT change pendant l’exécution d’une boucle, sa nouvelle valeur peut (mais pas toujours) être utilisée lors de la sélection des lignes suivantes. Il est préférable d’éviter de telles situations. Si vous avez besoin de ce comportement, vous devez tester le code avec soin et vous assurer que vous savez exactement comment les changements dans la variable affectent les résultats de la sélection. Je voudrais particulièrement noter que le comportement peut dépendre du plan de requête, en particulier des index utilisés. Il n’y a actuellement aucune règle stricte pour de telles situations, mais en