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 :

Utilisation de RAISERROR


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Utilisation de RAISERROR
    Salut,

    J'ai une PS qui fait un certain nombre de traitements dans un bloc de transaction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    begin transaction;
    	select @pos = isnull(MAX(pos), 0) + 1 from evp with(holdlock) where eve_id = @eve_id;
    	insert into evp (eve_id, pos, pro_id, qty) values (@eve_id, @pos, @pro_id, @qty);
    	set @new_id = SCOPE_IDENTITY();
    	exec p_DoMvt @fct_id, @eve_id, @pro_id, @qty, 1;
    commit;
    J'ai un trigger sur la table evp qui fait un RAISERROR avec une sévérité de 11.
    Je voudrais, sans devoir mettre un test à chaque ligne succeptible de planter :
    - Faire un rollback de ma transaction, puisque je suis dans une transaction et qu'elle est mal passée
    - Sortir de ma procédure

    Je pensais qu'une erreur non récupérée par un TRY CATCH allait produire ce comportement.
    Avec une sévirité de 1, le traitement continuait comme si de rien n'était.
    Avec une sévérité de 11, la traitement s'interromp dans la procédure (ici le trigger) mais continue normalement dans le bloc appelant.

    Je ne voudrais pas en arriver à l'extrême sévérité 25, qui stoppe la connexion SQL.

    Je ne trouve pas de documentation qui décrive chaque niveau de sévirité 1 à 1.
    Dois-je utiliser autrechose pour arriver à mes fins ?

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Est-ce que d'après vous, ce code fait ce que je cherche à faire ?

    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
     
    	begin try
    		begin transaction;
    		select @pos = isnull(MAX(pos), 0) + 1 from evp with(holdlock) where eve_id = @eve_id;
    		insert into evp (eve_id, pos, pro_id, qty) values (@eve_id, @pos, @pro_id, @qty);
    		set @new_id = SCOPE_IDENTITY();
    		exec p_DoMvt @fct_id, @eve_id, @pro_id, @qty, 1;
    		commit;
    	end try
    	begin catch
    		rollback transaction;
    		declare @err_msg varchar(4000);
    		declare @err_sev int;
    		set @err_msg = ERROR_MESSAGE();
    		set @err_sev = ERROR_SEVERITY();
    		RAISERROR(@err_msg, @err_sev, 1);
    	end catch;
    Y'a pas moyen de faire un truc moins usine à gaz???

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 986
    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 986
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    J'ai un trigger sur la table evp qui fait un RAISERROR avec une sévérité de 11.
    Pourquoi une sévérité de 11, c'est vous qu'y l'avez mis ainsi ? En principe lea classe d'erreur à utiliser pour les message perso c'est 16.
    A lire :
    http://www.sommarskog.se/error-handling-I.html
    paragraphe "More on Severity Levels"

    Mais la solution que vous donnez est fausse car on ne sait pas si la transaction est encore ouverte dans la partie CATCH (elle peut avoir été annulée dans le trigger !)
    Pour savoir quoi faire, utilisez la fonction XACT_STATE() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    begin catch
        IF XACT_STATE() <> 0
    		rollback transaction;
    		declare @err_msg varchar(4000);
    		declare @err_sev int;
    		SET @err_msg = ERROR_MESSAGE();
    		SET @err_sev = ERROR_SEVERITY();
    		RAISERROR(@err_msg, @err_sev, 1);
    	end catch;
    Par exemple.

    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/ * * * * *

  4. #4
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    D'accord.

    La severity 11, c'était effectivement de moi. J'ai trouvé entre temps qu'il vallait mieux mettre 16 (sans trop savoir pourquoi).
    Ceci dit, cela n'a rien changé au comportement du programme.

    OK pour votre solution.

    En revanche, ma question reste ouverte quant à la faisabilité du comportement suivant :

    Procédure A crée transaction
    Procédure A modifie des lignes
    Procédure A déclenche trigger B
    Trigger B crée une transaction
    Trigger B exécute des oppérations
    Trigger B plante
    "Vrai plantage".
    => Rollback implicite de trigger B
    => Arrêt immédiat de trigger B à l'endroit où l'erreur a été levée
    => Rollback implicite de procédure A
    => Arrêt immédiat de procédure A à l'endroit où l'erreur a été levée
    => (éventuellement, bouillonnement des rollback/arrêt immédiat au niveau des procédures appelantes)

    En gros, je cherche à reproduire ce qui se passerait avec un RAISERROR avec une sévérité de 25, mais en conservant la connexion ouverte.

    => En gros, je cherche a reproduire la notion d'exception comme elle existe dans les langages type C/C++/C# : on plante tous les traitements jusqu'à ce qu'il y en ait un qui trappe proprement l'erreur. Joint avec la notion de transaction, cela me permettrait de proprement revenir à l'état initial de mon instruction appelante, sans avoir à gérer des bouillonnements d'erreur et des imbrications de transactions à la main à tous les niveaux.

  5. #5
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    mieux mettre 16 (sans trop savoir pourquoi)
    Parce qu'elle est faite pour çà...

    Qu'appelez vous des "bouillonnements d'erreur"?

  6. #6
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Parce qu'elle est faite pour çà...

    Qu'appelez vous des "bouillonnements d'erreur"?
    Lorsque mon trigger plante et retourne une erreur de sévérité 16, l'appelant (que ce soit une fonction, procédure, autre trigger ou batch) ne plante pas, il continue à tourner.

    Je désire que l'instruction qui a délenché le trigger qui a planté soit en erreur elle aussi.

    Et ainsi de suite : si cette instruction est dans une fonction, alors je veux que la fonction soit en erreur, et que la requête appelante soit en erreur.

    => Jusqu'à ce que j'arrive à un bloc try/catch qui gère convenablement l'erreur, ou jusqu'à ce que dans mon programme appelant.

    Ainsi, si depuis mon programme j'appelle une procédure stockée, qui lance une fonction, qui délenche un trigger, qui exécute une ps qui lance une fonction, etc. etc. etc. plante, alors je veux que si je n'ai aucune gestion d'erreur, la procédure appelé par mon programme retourne l'erreur à mon programme et s'arrête là où il y a eu l'erreur.

    Exactement de la même façon que se comporte un programme classique (C, ADA, VB, Java...).

    En effet, je désire déporter au maximum les traitements de données dans des PS/Fonctions SQL, mais pour se faire, j'ai besoin d'avoir un minimum de mécanismes intelligents.

    Ce qui m'étonne, c'est que contraitement à SQL Server, Oracle fonctionne bel et bien comme ça : dès qu'une intruction plante, l'erreur est propagée à tous les niveaux et plante tous les traitements appelant s'ils ne gèrent pas l'erreur proprement. SQL Serveur se contente de continuer les traitements appelant, sans se soucier une seconde de l'intégrité du traitement.

  7. #7
    Membre Expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Billets dans le blog
    8
    Par défaut
    Ainsi, si depuis mon programme j'appelle une procédure stockée, qui lance une fonction, qui délenche un trigger, qui exécute une ps qui lance une fonction, etc. etc. etc. plante, alors je veux que si je n'ai aucune gestion d'erreur, la procédure appelé par mon programme retourne l'erreur à mon programme et s'arrête là où il y a eu l'erreur.
    Une fonction :
    • ne déclenche pas de trigger
    • n'exécute pas de PS
    • ne gère pas d'erreur

    Exactement de la même façon que se comporte un programme classique (C, ADA, VB, Java...).
    TSQL n'est pas un langage comme C, VB ou ...
    En effet, je désire déporter au maximum les traitements de données dans des PS/Fonctions SQL, mais pour se faire, j'ai besoin d'avoir un minimum de mécanismes intelligents.
    Présente le problème cas par cas et vous aurez une solution cas par cas.
    Ce qui m'étonne, c'est que contraitement à SQL Server, Oracle fonctionne bel et bien comme ça : dès qu'une intruction plante, l'erreur est propagée à tous les niveaux et plante tous les traitements appelant s'ils ne gèrent pas l'erreur proprement. SQL Serveur se contente de continuer les traitements appelant, sans se soucier une seconde de l'intégrité du traitement.
    Évite les comparaison inutiles et aborde chaque produit avec sa solution aux problèmes. Sache par ailleurs que la bête (SQL server) est tellement immense que ta solution peut juste être dans un paramètre ou plus de configuration.
    Vous me direz vos conclusions car je fais des recherches sur les "erreur" avec TSQL.
    Merci d'avance.

  8. #8
    Membre Expert

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Août 2007
    Messages : 1 216
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Je ne trouve pas de documentation qui décrive chaque niveau de sévirité 1 à 1.
    C'est decrit dans la doc SQL Server.
    http://msdn.microsoft.com/en-us/library/ms164086.aspx

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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