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 :

Procédures stockées et filtres "empilés"


Sujet :

Développement SQL Server

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut Procédures stockées et filtres "empilés"
    Bonjour à tous!

    Je suis en train de développer une interface avec une base de données qui affiche des résultats en fonction de filtres choisis par l'utilisateur, qu'il peut bien sûr superposer. J'aimerais écrire des procédures stockées pour ces requêtes, mais je m'aperçois que selon les critères choisis ou non, je dois en écrire énormément afin d'avoir toutes les combinaisons (j'ai 7 critères différents).

    Pourtant, cela doit être assez fréquent, ai-je manqué quelques chose? Pourrais-je écrire une procédure stockée où les paramètres d'entrée peuvent être ignorés? Je travaille sous SQL Server 2005 pour information.

    voici un exemple de ma procédure:
    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
     
    CREATE PROCEDURE [dbo].[P_ProducerSearch]  
    	-- Add the parameters for the stored procedure here
    	@Variety	varchar(100) = '*',
    	@Region		varchar(100) = '*',
    	@Country	varchar(100) = '*',
    	@Color		int = 0
     
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
    SELECT T_WineType.ProducerName 
    FROM T_WineType INNER JOIN T_Region ON T_WineType.RegionID = T_Region.RegionID 
    		INNER JOIN T_Country ON T_Region.CountryID = T_Country.CountryID 
    		INNER JOIN T_Wine ON T_WineType.WineTypeID = T_Wine.WineTypeID 
    		INNER JOIN T_Bottle ON T_Bottle.WineID = T_Wine.WineID 
    		LEFT JOIN T_Cepage ON T_Cepage.CepageID = T_WineType.CepageID
     
    WHERE T_WineType.VarietyName LIKE @Variety
    	AND T_Region.RegionName LIKE @Region
    	AND T_Country.CountryName LIKE @Country
    	AND T_WineType.Color = @Color
     
    END
    Dans ce cas, j'ai mis '*' comme valeur par défaut, mais ça ne marche pas. il faudrait une valeur par défaut qui soit ignorée par la requête en fait (même chose pour la valeur entière).


    Merci d'avance pour votre aide, et bonnes fêtes de fin d'année!

    Frédéric.

  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 992
    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 992
    Billets dans le blog
    6
    Par défaut
    Il serait plus simple de faire cela en SQL dynamique.

    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
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut
    Merci de ta réponse, actuellement c'est de cette façon que je procède, je pensais pouvoir le faire avec une procédure stockée...

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Je pense que SQLPro entendait par SQL dynamique le fait de construire la chaîne de requête dans une procédure stockée.
    Vous pouvez en plus de cela utiliser la procédure stockée système sp_executeSQL qui vous procurera un peu plus de puissance et une meilleure réutilisation de votre cache de plans, en testant si vos paramètres d'entrée sont NULL ou pas, par exemple ...

    @++

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut
    Salut Elsuket,

    Merci de cette précision, j'avais mal compris. Pour le moment, je construis ma requête dans mon code c++, selon les choix de l'utilisateur, puis je l'execute grâce à un objet ADO.

    Finalement, ce que tu me proposes, c'est de faire la même chose dans une procédure stockée, donc en utilisant des IF...ELSE afin de tester tous les paramêtres d'entrée? Mais puisque la requête est différente selon les cas, comment le plan d'execution peut-il être précompilé?

    Concernant sp_executeSQL (merci de l'info!), tu me conseilles donc de l'utiliser à l'intérieur de ma procédure stockée?


    Encore une fois, merci de ton aide,

    Frédéric.

    EDIT: en cherchant un peu du côté des requêtes dynamiques, je trouve plein de posts intéressants, je risque donc de tomber sur la solution...

  6. #6
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Mais puisque la requête est différente selon les cas, comment le plan d'execution peut-il être précompilé?
    Les plans de requête sont pré-compilés aux valeurs des paramètres près.
    D'ailleurs si vous faites une session de SQL Profiler, vous verrez passer des paramètres dans les RPC avec @p1 = uneValeur, ... : c'est de cela qu'il s'agit

    Finalement, ce que tu me proposes, c'est de faire la même chose dans une procédure stockée, donc en utilisant des IF...ELSE afin de tester tous les paramêtres d'entrée?
    Oui, à l'avantage de T-SQL que si vous avez besoin de changer le code sans changer les paramètres d'entrée, il vous suffit de recompiler la procédures stockée

    Concernant sp_executeSQL (merci de l'info!), tu me conseilles donc de l'utiliser à l'intérieur de ma procédure stockée?
    Tout à fait

    EDIT: en cherchant un peu du côté des requêtes dynamiques, je trouve plein de posts intéressants, je risque donc de tomber sur la solution...
    Vous pouvez effectivement vous en servir comme source d'inspiration, mais dans votre cas vous devrez "valuer" par défaut vous paramètres d'entrée à NULL, et réaliser vos appels en C++ en nommant les paramètres

    @++

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut
    Merci de tes précisions, je crois que j'ai compris comment faire, par contre, cela m'amène à plusieurs interrogations d'ordre général:

    - Si l'on peut générer n'importe quelle requête dans une procédure stockée, il n'y a aucun intérêt à le générer ailleurs (dans le code de l'IU par exemple)?

    - Je pensais que les procédures stockées gardaient en mémoire toujours le même plan d'exécution, c'est cela qui leur permettait d'être plus rapide. Mais d'après ce que tu me dis, le plan varie en fonction des paramètres d'entrée, où est-donc le gain de vitesse alors?


    Frédéric.

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Si l'on peut générer n'importe quelle requête dans une procédure stockée, il n'y a aucun intérêt à le générer ailleurs (dans le code de l'IU par exemple)?
    Les frameworks comme les SGBDR sont majoritairement mal utilisés.
    J'ai également écrit un petit billet autour de votre question

    Mais d'après ce que tu me dis, le plan varie en fonction des paramètres d'entrée, où est-donc le gain de vitesse alors?
    Attention, j'ai écrit :

    Citation Envoyé par elsuket
    Les plans de requête sont pré-compilés aux valeurs des paramètres près.
    Ce qui veut dire que pour la même chaîne de caractères, si seules les valeurs des paramètres changent, alors le même plan de requête est réutilisé.
    C'est ce qui explique les @p1 que vous pouvez voir, comme je vous l'ai dit, dans l'interface graphique de SQL Profiler.
    Néanmoins, si cela procure la plupart du temps de bonnes performances, c'est aussi cela qui est à l'origine des problèmes de parameter sniffing

    @++

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Par défaut
    Super, merci Elsuket pour ces précisions!

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

Discussions similaires

  1. procédure stockée filtre conditionnel
    Par Zobbiwan dans le forum Développement
    Réponses: 4
    Dernier message: 04/10/2008, 13h11
  2. Explication procédure stockée
    Par underworld dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/09/2002, 10h51
  3. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 12h27

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