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 :

StoredProcedure avec Filtre


Sujet :

MS SQL Server

  1. #1
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 180
    Points : 4 496
    Points
    4 496
    Par défaut StoredProcedure avec Filtre
    Bonjour,

    Quelle technique opteriez vous quand vous avez 2 requetes quasi identique
    mais où la clause where à des paramètres en plus

    Exemple:
    SP1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select  * From Etudiant Where Nom=@Nom
    et une autre
    SP2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select  * From Etudiant Where Nom=@Nom AND Prenom=@Prenom
    bon ici la requete est basique, juste pour illustré le propos mon vrai cas le select se fait sur plusieurs tables avec des jointures

    Vous pensez qu'il est mieux:
    -d'utiliser 2 procédures différentes
    -créer un if "select ... ELSE select ...."?
    -créer un string et utilisé "sp_executeSQL"
    -autre?

  2. #2
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Est-ce que dans tous les cas vous pouvez transmettre tous les paramètres, à NULL par exemple ?

    Dans ce cas vous pourriez faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT  * FROM Etudiant WHERE Nom=@Nom AND Prenom=COALESCE(@Prenom, Prenom)
    Je ne sais pas si c'est la solution optimale mais ça permet de ne conserver qu'une procédure.
    Je me demande si le moteur SQL détecte l'aberration de la clause et fait en sorte de ne pas perdre de temps... ?

  3. #3
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Le processeur de requêtes créera un plan de requêtes avec les paramètres de la première exécution de la procédure stockée.
    En conséquence, il faut mieux écrire un IF ... ELSE.

    Cependant, si vous avez de nombreux paramètres, il vaut mieux construire la chaîne de requête au fil de l'eau en testant le NULLité de la valeur des paramètres, puis soumettre la requête à l'aide de la procédure stockée sp_executesql, qui vous permettra à coup sûr d'avoir un plan par jeu de paramètres lorsque ceux-ci ne sont pas à NULL.

    @++

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 180
    Points : 4 496
    Points
    4 496
    Par défaut
    Dans ce cas si j'ai 4 paramètres (a,b,c,d) dont 2 peuvent être null (c,d)
    donc j'ai :
    2 valeurs (a,b), 2 null (c,d)
    3 valeurs (a,b,c), 1 null (d)
    3 valeurs (a,b,d), 1 null (c)
    4 valeurs (a,b,c,d)

    quand j'ai la requête dans le code (.net) de mon programme j'ajoute à la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If(c!=null) sqlwhere+="AND c=" & c
    mais vu qu'ici c'est une SP et vu qu'en SQL on ne peux pas faire mais par ca marche moins bien

  5. #5
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Il suffisait de faire ce que je vous ai suggéré :

    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
    32
    33
    34
    35
    36
    CREATE PROCEDURE usp_etudiant_recherche
    	@_a varchar(32)
    	, @_b varchar(32)
    	, @_c varchar(32) = NULL
    	, @_d varchar(32) = NULL
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	DECLARE @sql nvarchar(1024)
     
    	IF @_a IS NULL
    	BEGIN
    		RAISERROR('Le paramètre @_a doit être valué', 16, 1)
    		RETURN
    	END
     
    	IF @_b IS NULL
    	BEGIN
    		RAISERROR('Le paramètre @_b doit être valué', 16, 1)
    		RETURN
    	END
     
    	SET @sql = N'SELECT desColonnes FROM dbo.edutiant WHERE a = @_a AND b = @_b'
     
    	SELECT @sql = CASE WHEN @_c IS NOT NULL THEN ' AND c = @_c' ELSE '' END
    	SELECT @sql = CASE WHEN @_d IS NOT NULL THEN ' AND d = @_d' ELSE '' END
     
    	EXEC sp_executesql
    		@sql
    		, N'@_a varchar(32), @_b varchar(32), @_c varchar(32), @_d vachar(32)'
    		, @_a = @_a
    		, @_b = @_b
    		, @_c = @_c
    		, @_d = @_d
    END
    On doit contrôler que les paramètres @_a et @_b ne sont pas NULL parce qu'on peut faire l'appel à la procédure stockée en let mettant à NULL.

    mais vu qu'ici c'est une SP et vu qu'en SQL on ne peux pas faire

    mais par

    ca marche moins bien
    Oui, parce qu'en SQL, NULL n'est pas une valeur
    C'est pourquoi on utilise IS et par égale

    @++

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 180
    Points : 4 496
    Points
    4 496
    Par défaut
    Merci

    juste une petite correction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT @sql = @sql + CASE WHEN @_c IS NOT NULL THEN ' AND c = @_c' ELSE '' END
    SELECT @sql = @sql + CASE WHEN @_d IS NOT NULL THEN ' AND d = @_d' ELSE '' END

  7. #7
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Effectivement, merci de l'avoir relevé, et ravi de vous avoir aidé

    @++

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 180
    Points : 4 496
    Points
    4 496
    Par défaut
    Une autre façon de faire est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Select * From etudiant 
    Where c = ISNULL(@_c, etudiant.c) OR ( etudiant.c is null and @_c is null)
    Ca a l'avantage d'être compilé par le compilateur

    ps: en relisant le post j'ai vu que j'avais zappé le message de Jinroh77
    COALESCE c'est l'équivalent du IsNull mais sans le OR ( etudiant.c is null and @_c is null) les rows qui ont c à null ne seront pas renvoyés

  9. #9
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Cela fonctionne effectivement, mais le filtre n'est pas cherchable.
    En conséquence, à chaque fois que vous exécuterez la requête, elle lira toute la table.

    En revanche avec la solution que je vous propose, si les colonnes c et d sont supportées par un index, la requête sera plus performante.

    @++

  10. #10
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 180
    Points : 4 496
    Points
    4 496
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Cela fonctionne effectivement, mais le filtre n'est pas cherchable.
    En conséquence, à chaque fois que vous exécuterez la requête, elle lira toute la table.
    Pourquoi?

    Je ne vois pas la différence

  11. #11
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Parce que SQL Server maintient des statistiques sur les valeurs qui sont dans les colonnes, pas sur les valeurs des fonctions qu'on peut appliquer à une colonne.
    De la même façon un prédicat OR n'est souvent pas cherchable : il est possible de dire, à partir des statistiques, si une colonne contient une valeur et (AND) une aussi, mais pas si une colonne contient une valeur ou (OR) une autre en contient une autre

    @++

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

Discussions similaires

  1. Problème avec filtre d'un formulaire ?
    Par HookerSeven dans le forum Access
    Réponses: 3
    Dernier message: 25/02/2006, 01h59
  2. [VBA EXCEL] Protection feuille avec filtre auto
    Par mirumoto dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 16/01/2006, 10h48
  3. compteur de ligne excel avec filtre
    Par calimero91 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 14/12/2005, 11h04
  4. Requete avec filtre sur un champ
    Par podz dans le forum Langage SQL
    Réponses: 7
    Dernier message: 09/02/2005, 14h37
  5. [Plugin] Bouton browse projet avec filtre
    Par jcarre dans le forum Eclipse Platform
    Réponses: 4
    Dernier message: 09/04/2004, 13h56

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