IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Tester dans une procédure si un trigger à fait un raiserror


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 43
    Par défaut Tester dans une procédure si un trigger à fait un raiserror
    Bonjour,

    Voici la situation :

    J'ai une procédure qui exécute entre autre un insert sur une table, là le trigger insert de la table prend le relai et effectue des tests, en cas de soucis il envoie un raiserror.

    Mon problème c'est que je ne sais pas comment savoir dans ma procédure si mon insert via le trigger a renvoyé une erreur.

    Dans ma procédure j'ai tenté un truc du style mais cela ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    INSERT INTO MA_TABLE (x, y,z) values (a,b,c);
    IF @@ERROR <> 0
     Return;
    @@ERROR reste désespérément à 0.

    J'ai trouvé une solution de contournement, je sauvegarde le prochain identifiant de ma table avant l'insert, le prochain identifiant après l'insert et je les compare, s'ils sont égaux, l'insert c'est pas bien passé et je sors de la procédure.

    N'y a-t-il pas un moyen plus propre ?

    Merci d'avance
    Aerofly

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 999
    Billets dans le blog
    6
    Par défaut
    Il faut utiliser un bloc TRY/CATCH. En effet un trigger est ensembliste et atomique par principe....

    Démo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE TABLE T (I INT);
    GO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TRIGGER E_I_T
    ON T
    AFTER INSERT
    AS
       SELECT 1/0;
    GO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE PROCEDURE P
    AS
    BEGIN TRY
       INSERT INTO T VALUES (0);
    END TRY
    BEGIN CATCH
       RAISERROR('Erreur lors de l''insertion', 16, 1);
    END CATCH
    GO
    Msg*50000, Niveau*16, État*1, Procédure*P, Ligne*7
    Erreur lors de l'insertion


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 43
    Par défaut
    Merci pour la réponse

    Effectivement je peux englober l'insert dans un try catch mais ça me bloque pour la suite :/
    Le trigger renvoie une erreur personnalisée paramétrable avec un certain numéro, numéro dont je me sers plus tard. En fait la procédure est appelé par du code c# et c'est à ce niveau entre autre que je gère la transaction et que je traite l'erreur en fonction du code erreur. La si je renvoi un raiserror dans la procédure, je perds cette info.

    Aerofly

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 999
    Billets dans le blog
    6
    Par défaut
    Vous commettez deux erreurs :
    1) commencez vos transaction côté client est la pire des choses... En effet cela allonge démentiellement les temps de blocage des tables du fait des aller et retour réseau. Bref de quoi pourrir les performances !
    2) un trigger est au sein de la transaction. Il est donc inutile de démarrer une transaction pour englober le code procédural d'un trigger !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Il faut utiliser un bloc TRY/CATCH.
    Citation Envoyé par Aerofly Voir le message
    La si je renvoi un raiserror dans la procédure, je perds cette info.
    Il suffit de NE PAS mettre de Try/Catch, et l'erreur du Trigger remontera jusqu'au code appelant C#, avec ses infos personnalisés !
    Ce qui n'empêche pas d'englober le tout dans une transaction coté serveur, avec set XACT_ABORT ON.
    Et pour savoir dans le code T-SQL si le Trigger a bloqué l'insert,
    on pourrait peut-être récupérer les lignes insérés avec OUTPUT pour les compter ensuite ?

Discussions similaires

  1. Réponses: 8
    Dernier message: 16/09/2011, 19h35
  2. Réponses: 13
    Dernier message: 27/04/2011, 10h13
  3. passage d'un nom de table dans une procédure stockée
    Par thierry V dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 26/07/2010, 16h48
  4. [Firebird] Désactiver des Triggers dans une procédure
    Par Cazaux-Moutou-Philippe dans le forum Bases de données
    Réponses: 5
    Dernier message: 28/10/2007, 09h07
  5. Réponses: 9
    Dernier message: 31/01/2006, 09h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo