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 :

Meilleure syntaxe d'appel de procédures stockées dans une procédure stockée


Sujet :

Développement SQL Server

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut Meilleure syntaxe d'appel de procédures stockées dans une procédure stockée
    Bonjour,
    J'utilise SQL server depuis 2003, et j'ai l'habitude dans une procédure stockée d'appeler d'autres procédures stockées ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = Ma_Procedure @mon_parametre = 10
    or dans ma nouvelle équipe l'habitude est d'écrire un appel ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DECLARE @vStored_Launched	nvarchar(126)
    SET @vStored_Launched = 'Ma_Procedure'
    EXECUTE @vResult = @vStored_Launched 	@mon_parametre =10
    Outre le fait qu'on perd les informations de dépendance (sp_depends Ma_Procedure ne renvoie rien), y a-t-il des avantages ou des inconvénients à utiliser cette façon de faire.
    Merci de votre aide
    Soazig

  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 763
    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 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Ni ll'un ni l'autre ne sont correct.

    La bonne forme est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DECLARE @RETVAL ...
    EXECUTE Ma_Procedure @mon_parametre , @RETVAL OUTPUT;
    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 éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Merci sqlpro,
    Mais je ne vois pas pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = Ma_Procedure @mon_parametre
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = Ma_Procedure @mon_parametre = 10
    ne serait pas corrects
    Toutes les syntaxes que j'ai proposé fonctionne. Ma question est laquelle est la meilleure et pourquoi (avantage et inconvénient de chaque syntaxe)
    Voici un code de test qui fonctionne
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    IF EXISTS (
      SELECT * 
        FROM INFORMATION_SCHEMA.ROUTINES 
       WHERE SPECIFIC_SCHEMA = N'dbo'
         AND SPECIFIC_NAME = N'Ma_Procedure' 
    )
       DROP PROCEDURE dbo.Ma_Procedure
    GO
     
    CREATE PROCEDURE dbo.Ma_Procedure
    	@mon_parametre int = 0
    AS
    	SELECT @mon_parametre as Mon_param
    	return 0
    GO
     
    -- =============================================
    -- Example to execute the stored procedure
    -- =============================================
    DECLARE @RETVAL int
    EXECUTE @RETVAL=dbo.Ma_Procedure 10
     
    EXECUTE @RETVAL = Ma_Procedure @mon_parametre = 10
    declare @mon_parametre int
    set @mon_parametre=10
    EXECUTE dbo.Ma_Procedure @mon_parametre 
     
    DECLARE @vStored_Launched	nvarchar(126)
    SET @vStored_Launched = 'Ma_Procedure'
    EXECUTE @RETVAL = @vStored_Launched 	@mon_parametre =10
    GO
    Merci
    Soazig

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = Ma_Procedure @mon_parametre = 10
    Ça marche, mais c'est illisible.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = @Ma_Procedure @mon_parametre = 10
    C'est encore moins lisible, et laisse la porte ouverte aux injections SQL, surtout si la valeur de @Ma_Procedure est reçue en paramètre (ce qui est d'ailleurs le seul et unique cas où cette syntaxe a le moindre intérêt).

    Rappel du premier cours de première année de programmation de n'importe quel cursus de programmation :
    - une PROCEDURE FAIT quelque chose
    - une FONCTION VAUT quelque chose

    Une PROCEDURE ne doit donc rien retourner, elle ne doit pas contenir de clause RETURN.
    Donc sémantiquement, exec @res = MaProc c'est pas correct.

    Une PROCEDURE peut en revanche avoir des paramètres optionnels ou non, avec une direction (INPUT par défaut, OUTPUT en option).
    Et une PROCEDURE peut avoir plusieurs paramètres OUTPUT, à ce moment, ta syntaxe ne fonctionne juste pas (ou alors ne fait clairement pas son boulot).

    Enfin, les paramètres nommés, c'est une très mauvaise habitude, à mon avis. Cela signifie que tu as l'habitude de changer l'ordre des paramètres et leur nombre dans la déclaration de tes procédures.

    La seule utilité des paramètres nommés dans l'appel d'une procédure, c'est de "sauter" des paramètres optionnels. Par convention, ces derniers sont rejetés en fin de liste des paramètres, et donc n'ont pas besoin d'être "sauté" la plupart du temps.

    Donc pour une procédure :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    create procedure MaProc
    (
       @param1 int,
       @param2 int,
       @param3 int output,
       @param4 int output,
       @param5 int = 4
    )
    [...]

    On utilisera simplement la syntaxe :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    declare @res1 int;
    declare @res2 int;
     
    exec MaProc 1, 2, @res1 output, @res2 output;

    Ce qui est quand même plus lisible que :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    declare @res int;
     
    exec @res = MaProc @param1 = 1, @param2 = 2;
    Surtout qu'on sait pas trop ce que va contenir @res
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    bonjour,

    Citation Envoyé par StringBuilder Voir le message
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = Ma_Procedure @mon_parametre = 10
    Ça marche, mais c'est illisible.
    La ça se discute, car tu pourrais imaginer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     execute Ma_Procedure @nbre_choux=10, @nbre_carottes=15
    et ton appel préféré
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     execute Ma_Procedure 10, 15
    Avec ton appel préféré on ne sait pas en lisant le code si le premier paramètres concerne les choux ou les carottes ou les navets. Je te l'accorde c'est le cas dans la plupart des langages.
    Citation Envoyé par StringBuilder Voir le message
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = @Ma_Procedure @mon_parametre = 10
    C'est encore moins lisible, et laisse la porte ouverte aux injections SQL, surtout si la valeur de @Ma_Procedure est reçue en paramètre (ce qui est d'ailleurs le seul et unique cas où cette syntaxe a le moindre intérêt).
    Là, je suis d'accord, c'est exactement le genre d'argument que je cherchais, et auquel je n'avais pas pensé.
    Citation Envoyé par StringBuilder Voir le message
    Rappel du premier cours de première année de programmation de n'importe quel cursus de programmation :
    - une PROCEDURE FAIT quelque chose
    - une FONCTION VAUT quelque chose

    Une PROCEDURE ne doit donc rien retourner, elle ne doit pas contenir de clause RETURN.
    Donc sémantiquement, exec @res = MaProc c'est pas correct.
    Dans beaucoup de projets et pas uniquement dans mon équipe, lavaleur de retour d'une procédure stockée vaut 0 quand tout va bien et un code erreur sinon.
    Certes ce n'est plus nécessaire depuis l'ajout du try catch en SQL server 2005, mais les habitudes ont la vie dure.

    Pour tout te dire, je n'ai pas l'habitude des valeurs de retour, mais elles sont utilisées dans le projet sur lequel je travaille.
    PS: si vous avez d'autres inconvénients à ajouter sur le fait de passer le nom de la procédure stockée en paramètre.
    Merci pour vos réponses
    Soazig

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Pour le coup des paramètres non nommés illisibles, je sais pas trop avec outils vous travaillez, mais moi, je travaille simplement avec SQL Server Management Studio, qui est gratuit, et il y a l'intellisense...

    Code sql : 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
     
    create procedure Potee
    (
    	@nb_choux int,
    	@nb_navet int,
    	@nb_carotte int = 5,
    	@volume_eau int output
    )
    as
    begin
       select @volume_eau = @nb_choux + @nb_navet / 2. + @nb_carotte / 5.;
    end;
     
    declare @litres int;
    exec Potee 2, 8, default, @litres output;
    select @litres;

    Lorsque je saisi ma ligne "exec Potee", j'ai ça :
    Nom : intellisense_ssms.png
Affichages : 143
Taille : 4,6 Ko

    Donc si exec Potee 2, 8, default, @litres output; ne semble pas très lisible au premier abord, j'ai juste à passer la souris devant pour voir les paramètres.
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Merci StringBuilder, je connaissais cette possibilité.
    Pour la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE @vResult = @Ma_Procedure @mon_parametre = 10
    Avez vous d'autres remarques sur ses performances, défauts ...
    Ce pour que je puisse convaincre mes camarades de faire autrement, mais il me faut des arguments.
    Pour l'instant j'ai comme argument
    • sp_depends ne trouve rien
    • risque d'injection de sql (même si dans notre cas d'utilisation la procédure stockée n'est jamais un paramètre externe et est toujours une variable locale)

    Je ne sais pas si ça plombe les performances ou pas.

    Merci de vos réponses
    Soazig

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 698
    Points : 586
    Points
    586
    Par défaut
    Si j'ai bien compris la questions c'est "vaut-il mieux avoir le nom de la procédure dans un paramètre ou en dur dans l'appel ?"

    Auquel cas la réponse est dans la question

  9. #9
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Je serais tenté de dire, à la lumière de la MSDN, qu'un EXECUTE sur un littéral tourne avec son propre contexte.

    Par conséquent, j'imagine que ça a un impact pénalisant sur les performances. Cependant, aucune certitude.

    Ceci dit, dans votre cas, j'imagine qu'il n'y a pas de changement de contexte, et SQL Server doit être assez intelligent pour du coup conserver le contexte actuel.

    En contre partie, si vos procédures changent le contexte (use database par exemple) alors entre un execute sur la procédure ou sur un littéral contenant la procédure ne produira pas le même résultat ! (avec le littéral, on retrouve le contexte initial au retour de la procédure).
    On ne jouit bien que de ce qu’on partage.

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    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 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Au niveau des performances il n'y aura aucune différence quel que soit la syntaxe d'appel, la requête étant ré-interprété à la volée.

    Au niveau de l'exécution, le simple fait de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXEC @maVariable = MaProc...
    n'a pas de sens, car le résultat capté par @maVariable sera toujours le code d'erreur de la procédure.
    Ce qui serait encore plus stupide, c'est que vous ayez forcé une valeur de RETURN dans le code de votre procédure écrasant ainsi le code d'erreur !
    C'est pourquoi cette syntaxe est imbécile.

    Si vous voulez une valeur de retour il faut préciser un paramètre en OUTPUT.

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

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 506
    Points : 1 289
    Points
    1 289
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Ce qui serait encore plus stupide, c'est que vous ayez forcé une valeur de RETURN dans le code de votre procédure écrasant ainsi le code d'erreur !
    Je suis perplexe devant cette affirmation, tant SQL92 que SQL Server prévoient qu'une procédure contienne (potentiellement) des instructions return qui renvoie un nombre entier, et la lecture de ce return en SQL Server se fait bien par
    EXEC @return_status = checkstate '12345678901';

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 506
    Points : 1 289
    Points
    1 289
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Rappel du premier cours de première année de programmation de n'importe quel cursus de programmation :
    - une PROCEDURE FAIT quelque chose
    - une FONCTION VAUT quelque chose
    C'est vrai, avec l'extrème si on suit les recommendations de Bertrand Meyer (OOSC Construction 2007) que les procédures ne peuvent RIEN retourner (pas de paramètres output) et les fonctions RIEN modifier (aucun effet de bord).

    MAIS en SQL (tant SQL92 que SQL Server) une procédure retourne bien un entier avec l'instruction Return.

Discussions similaires

  1. Appels de procedures stockées dans une proc stockée ?
    Par Nadaa dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 17/07/2008, 10h32
  2. Réponses: 3
    Dernier message: 28/08/2007, 15h21
  3. Appel d'une procédure stockée dans une procédure stockée
    Par MrEddy dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 13/09/2006, 16h17
  4. Réponses: 3
    Dernier message: 17/01/2006, 17h12
  5. Réponses: 3
    Dernier message: 21/09/2004, 07h35

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