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

MS SQL Server Discussion :

Gestion des transactions - Gestion des erreurs


Sujet :

MS SQL Server

  1. #1
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut Gestion des transactions - Gestion des erreurs
    Salut,
    voila j'ai un problème de compréhension des transactions dans sql server.
    J'ai une procédure principale, qui lance plusieurs procédures secondaires.
    Je voudrais pouvoir en cas d'erreur sur la procédure principale ou les procédures secondaires, annuler l'ensemble du traitement. Je voudrais également remonter l'erreur et la stocker dans une table.
    Ou dois je mettre ma transaction ( seulement dans la procédure principale ? )
    Ou dois je mettre ma récup d'erreur ?

    merci d'avance

  2. #2
    Membre expert
    Avatar de trotters213
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 571
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gard (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 571
    Points : 3 145
    Points
    3 145
    Par défaut

    Tu devrais essayer en utilisant les procédures stockées et la gestion des erreurs.
    Regarde ici et il explique à merveille

  3. #3
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut "On error" dans sql server ?
    Ok, j'ai compris le fonctionnement des transactions et j'ai fait un test qui tourne. Par contre, j'ai un problème sur la gestion des erreurs.
    Doit on obligatoirement mettre if @@error<>0 après chaque instruction sql ou existe t-il une instruction du style "on error goto.... "

    merci d'avance

  4. #4
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    voila je poste mon code pour être précis..
    Ma question : comment je fais pour gérer les erreurs dans test_transaction_tri et test_transaction_bis autrement que par if @@error<>0 ? Sur cette procédure exemple, il y a qu'une seule instruction sql donc c'est pas génant, par contre sur une grande procédure, il doit y avoir un moyen de ne pas mettre if @@error<>0 a chaque fois ?

    CREATE PROCEDURE test_transaction AS
    declare @i int
    set @i=0
    declare @test int
    while @i<5

    begin
    begin transaction transaction_general

    exec @test=test_transaction_tri
    if @test=2
    goto annulation
    exec @test=test_transaction_bis
    if @test=2
    goto annulation
    commit transaction transaction_general
    goto fin

    annulation:
    rollback transaction transaction_general

    fin:
    set @i=@i+1
    end
    select @i
    GO
    -----------------------------------------
    CREATE PROCEDURE test_transaction_bis AS

    insert into valeur values('toto')
    if @@error<>0
    goto erreur

    return 1-- pour ok
    goto fin
    erreur:
    return 2-- pour nok
    fin:
    GO

    Merci de votre aide

  5. #5
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    personne n'a la réponse ?

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 19
    Points : 19
    Points
    19
    Par défaut
    Normalement il faut éviter l'instruction GOTO

    pour ce faire, tu peux faire comme suit :

    tout d'abord, tu ouvres une transaction
    puis, pour chaque appel d'une procédure stockée, tu crées une variable contenant le numéro de l'erreur déclanchée (Si elle est déclanchée)

    et enfin, tu fais la somme de tes vrariables:
    si le total est égal à 0, aucune erreur n'est déclanchée, tu commites
    sinon, tu rollback.

    voici un exemple,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    CREATE PROCEDURE test_transaction AS 
    declare @i int 
    set @i=0 
    declare @Proc1_error int 
    while @i<5 
     
    begin 
    begin transaction transaction_general 
     
    exec @test=test_transaction_tri 
    SELECT @Proc1_error = @@ERROR
     
    exec @test=test_transaction_bis
    SELECT @Proc2_error = @@ERROR
     
    if &#40;@Proc1_error  + @Proc2_error = 0&#41;
       commit transaction_general
    else
       rollback transaction_general
     
    end

  7. #7
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 19
    Points : 19
    Points
    19
    Par défaut
    en fait c'est le seul myen que j'ai trouvé pour écrire proprememnt mon code.

    Quant à la journalisation de l'erreur tu peux l'effectuer au niveau de l'instruction rollback, c'est à dire tu doix chercher quel instruction à déclancher l'erreur pour faire ton traitement

  8. #8
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    merci pour ta réponse MokhTelnet, c'est vrai que ton code est plus propre. Mais il ne résoud pas mon problème
    Le problème est que la variable @@error est égal à 0 si la dernière instruction sql de la procédure test_transaction_bis est ok ( si j'ai une instruction non ok, suivie d'une instruction ok, @@error sera égal à 0 )
    Moi je veux annuler toute la transaction dès que je rencontre une erreur dans ma procédure test_transaction_bis.
    C'est pour ca que je veux savoir comment intercepter une erreur autrement que par if @@error<>0

    si tu peux m'aider

  9. #9
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 19
    Points : 19
    Points
    19
    Par défaut
    je suis désolé mais ma solution réponds parfaitement a ton besoin

    c vrai que @@error peux renvoyer un eentier différent de 0 puis un entier égale à 0 dans la'ppele de la deuxième procédure. mais le fait de conserver chaque résultat d'une procédure dans une variable indépendante permet de bien gérer ta transaction

    c vrai aussi que lorsqu'une erreur se déclanche en exécute comme meme la deuxième procédure. tu peux tester la valeur retourner avant l'appel de la deuxième procédure



    regarde un peu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    exec @test=test_transaction_tri 
    SELECT @Proc1_error = @@ERROR 
     
    exec @test=test_transaction_bis 
    SELECT @Proc2_error = @@ERROR
    vous pouvez avoir @Proc1_error = 100 et @Proc2_error = 0

    dans ce cas, on peut conclure q'une erreur c'est produite dans la première procédure.


    bonne chance

  10. #10
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    En fait, j'ai peut être mal formulé ma question. Je vais te donner un exemple précis.
    Supposons que j'ai une table "valeur" avec un seul champ, en clé primaire

    CREATE PROCEDURE test_transaction_tri AS
    insert into valeur values('toto')
    insert into valeur values('titi')
    insert into valeur values('tata')
    insert into valeur values('toto') erreur car doublon
    Les instructions insert sont des exemples, j'aurai pu mettre n'importe quelle autre instruction à la place

    Comment tester et renvoyer à la procédure test_transaction_general qu'il y a une erreur ou pas dans la procédure, à n'importe quel niveau ? Suis je obligé d'écrire après chaque insert, un test "if @@error<>0" ou existe t-il une instruction du style "on error goto..." à placer qu'une seule fois dans la procédure.
    Mes procédures sont très longues, ca m'étonne qu'il faille mettre un test après chaque instruction
    Merci, j'espère m'être bien expliqué

  11. #11
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 19
    Points : 19
    Points
    19
    Par défaut
    je crains que oui car la gestion d'erreur dans le transact SQL n'est pas trés élaborée, il n'y pas dinstruction on error goto (comme en VB) ou les bloc try catch (comme Java et DotNet)

    je ne sais pas s'ils ont amélioré ce point dans la nouvelle version de SQL server 2005.

  12. #12
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    ok merci bcp pour ton aide
    Je vais mettre un test après chaque instruction ( !!!!! ) et si je trouve une erreur, je fais un return @@error. Dans test_transaction_general, a chaque appel de la procédure, je teste la valeur retournée. Si c'est >0, j'annule la transaction.

    Je laisse ce post en 'non résolu', si quelqu'un a la réponse, merci d'avance.

  13. #13
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 220
    Points : 19 549
    Points
    19 549
    Billets dans le blog
    25
    Par défaut
    Non, vous n'y couperez pas.

    Par contre, pour reprendre votre exemple, si vous créez une SP qui fait un INSERT avec des paramètres et que vous gérez l'erreur, rien ne vous empêchera ensuite de faire des

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    CREATE PROCEDURE is_val &#40;@p varchar&#40;30&#41;&#41; 
    AS 
    insert into valeur values&#40;@p&#41;
    if @@error <> 0
    begin
    print 'erreur'
    raiserror 20001 'erreur'
    return -1
    else
    return 0
    end
     
    CREATE PROCEDURE test_transaction_tri AS 
    BEGIN
    exec is_val 'toto'
    exec is_val 'titi'
    exec is_val 'tata'
    exec is_val 'toto'
    END
    Sr DBA Oracle / MS-SQL / MySQL / Postgresql / SAP-Sybase / Informix / DB2

    N'oublie pas de consulter mes articles, mon blog, les cours et les FAQ SGBD

    Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !

  14. #14
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 19
    Points : 19
    Points
    19
    Par défaut
    franchement, je trouve que le help sur Transact SQL est mal fichue. normalement, lorsqu'on cherche de l'aide à propos de @@ERROR, il aurai dûe référencer la fonction RAISEERROR. Merci Fadace

    pour revenir a votre code je crois que tu as oublié la transaction qui doit se trouver au plus haut niveau test_transaction

  15. #15
    Membre habitué
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    417
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 417
    Points : 171
    Points
    171
    Par défaut
    ok merci a tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Gestion de projet: encodage des heures sur des tâches
    Par Terminator dans le forum Gestion de projet
    Réponses: 2
    Dernier message: 03/02/2015, 12h10
  2. Trigger pour mettre des droits sur des procedures et des vues
    Par briino dans le forum Développement
    Réponses: 3
    Dernier message: 23/09/2009, 10h44
  3. Réponses: 4
    Dernier message: 02/04/2008, 18h51
  4. Réponses: 3
    Dernier message: 13/09/2007, 19h11
  5. Réponses: 3
    Dernier message: 23/01/2007, 09h14

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