Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/10/2011, 13h17   #1
Invité de passage
 
Homme aziz amednagh
Développeur .NET
Inscription : juin 2010
Messages : 18
Détails du profil
Informations personnelles :
Nom : Homme aziz amednagh
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Communication - Médias

Informations forums :
Inscription : juin 2010
Messages : 18
Points : 4
Points : 4
Par défaut est-il possible de faire un where avec une liste en paramètre

Bonjour,
est-ce qu'il est possible de faire une requête (procédure stockée) avec comme paramètre une liste de données ?
je m'explique :
je veux envoyer une liste [a,b,c,d] a une procédure
et je veux faire une recherche avec ca, dire au système si mon ID existe dans [a,b,c,d]

select * from MaTable where ID exist dans [a,b,c,d]

je precise que je travail sur sql server 2005

merci par avance
amednagh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 13h38   #2
Membre expérimenté
 
Avatar de tumoo
 
Homme
Développeur informatique
Inscription : janvier 2011
Messages : 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 22
Localisation : France, Charente Maritime (Poitou Charente)

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2011
Messages : 309
Points : 550
Points : 550
Salut

Oui tu peux avec le mot clé IN

Code sql :
SELECT * FROM MaTable WHERE ID IN (a,b,c,d)
tumoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 14h05   #3
Invité de passage
 
Homme aziz amednagh
Développeur .NET
Inscription : juin 2010
Messages : 18
Détails du profil
Informations personnelles :
Nom : Homme aziz amednagh
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Communication - Médias

Informations forums :
Inscription : juin 2010
Messages : 18
Points : 4
Points : 4
non ca passe pas



Citation:
Envoyé par tumoo Voir le message
Salut

Oui tu peux avec le mot clé IN

Code sql :
SELECT * FROM MaTable WHERE ID IN (a,b,c,d)
amednagh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 14h12   #4
Membre expérimenté
 
Avatar de tumoo
 
Homme
Développeur informatique
Inscription : janvier 2011
Messages : 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 22
Localisation : France, Charente Maritime (Poitou Charente)

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2011
Messages : 309
Points : 550
Points : 550
Bah tu déclares 4 paramètres dans ta procédure,

et tu fais un

Code sql :
SELECT * FROM MaTable WHERE ID IN (@param1,@param2,@param3,@param4)

dans ta procédure

Pour l'appel,
Code sql :
exec ta_procédure @param1=a,@param2=b,@param3=c,@param4=d

Tu saisis le principe ?
tumoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 14h23   #5
Invité de passage
 
Homme aziz amednagh
Développeur .NET
Inscription : juin 2010
Messages : 18
Détails du profil
Informations personnelles :
Nom : Homme aziz amednagh
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Communication - Médias

Informations forums :
Inscription : juin 2010
Messages : 18
Points : 4
Points : 4
oui mais non lol
en fait y aura presque entre 1 et 2000 paramètres ca dépends des cases que l'utilisateur a coché dans un treeview (c#)



Citation:
Envoyé par tumoo Voir le message
Bah tu déclares 4 paramètres dans ta procédure,

et tu fais un

Code sql :
SELECT * FROM MaTable WHERE ID IN (@param1,@param2,@param3,@param4)

dans ta procédure

Pour l'appel,
Code sql :
exec ta_procédure @param1=a,@param2=b,@param3=c,@param4=d

Tu saisis le principe ?
amednagh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2011, 11h08   #6
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Bonjour,

C'est un problème récurrent et il existe trois façons de le résoudre :

- soit vous faites un INSERT dans une table à deux colonnes, réservée à cet effet : l'une est un identifiant de type uniqueidentifier, généré par la procédure stockée avec la fonction NEWSEQUENTIALID(), et vous stockez toutes les valeurs dans cette colonne.
Ensuite vous faites la jointure sur cette table en filtrant par l'identifiant

- soit vous utilisez des paramètres de type TABLE (TVP dans la littérature), qui sont plus stricts.
Mais comme ce sont des variables de type TABLE côté SQL Server, aucune statistique n'est maintenue sur une telle table (elle est stockée dans TempDB).
Donc l'estimation de cardinalité pour un grand nombre de valeurs est souvent faux à moins que vous terminiez la requête par OPTION (RECOMPILE).
Dans ce dernier cas, si la requête est exécutée très fréquemment, vous allez augmenter la consommation de CPU.

- Soit vous utilisez une fonction SQL de dépouillement de la chaîne, et vous faites une jointure sur la fonction table.
Vous aurez le même problème d'estimation de cardinalité que ci-dessus.

Code :
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
CREATE TABLE dbo.nombre
(
	nombre int NOT NULL CONSTRAINT PK_Nombres PRIMARY KEY CLUSTERED
)
 
SET NOCOUNT ON
 
DECLARE	 @max AS INT,
	@i AS INT
 
SELECT @max = 100000;
	, @i = 1;
 
WHILE @i<= @max
BEGIN
	INSERT dbo.nombre SELECT @i
	SET @i += 1
END
 
CREATE FUNCTION dbo.SplitStringToInt
	(
		@string AS VARCHAR(max)
	)
RETURNS TABLE
AS
	RETURN
		SELECT	CAST(SUBSTRING(@string, nombre, CHARINDEX(',', @string + ',', nombre) - nombre) AS int) AS element
		FROM	dbo.nombre
		WHERE	nombre<= LEN(@string) + 1
		AND	SUBSTRING(',' + @string, nombre, 1) = ','
GO
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2011, 11h45   #7
Invité de passage
 
Homme aziz amednagh
Développeur .NET
Inscription : juin 2010
Messages : 18
Détails du profil
Informations personnelles :
Nom : Homme aziz amednagh
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Communication - Médias

Informations forums :
Inscription : juin 2010
Messages : 18
Points : 4
Points : 4
supeeeer merci Nicolas pour toutes ses explications



Citation:
Envoyé par elsuket Voir le message
Bonjour,

C'est un problème récurrent et il existe trois façons de le résoudre :

- soit vous faites un INSERT dans une table à deux colonnes, réservée à cet effet : l'une est un identifiant de type uniqueidentifier, généré par la procédure stockée avec la fonction NEWSEQUENTIALID(), et vous stockez toutes les valeurs dans cette colonne.
Ensuite vous faites la jointure sur cette table en filtrant par l'identifiant

- soit vous utilisez des paramètres de type TABLE (TVP dans la littérature), qui sont plus stricts.
Mais comme ce sont des variables de type TABLE côté SQL Server, aucune statistique n'est maintenue sur une telle table (elle est stockée dans TempDB).
Donc l'estimation de cardinalité pour un grand nombre de valeurs est souvent faux à moins que vous terminiez la requête par OPTION (RECOMPILE).
Dans ce dernier cas, si la requête est exécutée très fréquemment, vous allez augmenter la consommation de CPU.

- Soit vous utilisez une fonction SQL de dépouillement de la chaîne, et vous faites une jointure sur la fonction table.
Vous aurez le même problème d'estimation de cardinalité que ci-dessus.

Code :
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
CREATE TABLE dbo.nombre
(
	nombre int NOT NULL CONSTRAINT PK_Nombres PRIMARY KEY CLUSTERED
)
 
SET NOCOUNT ON
 
DECLARE	 @max AS INT,
	@i AS INT
 
SELECT @max = 100000;
	, @i = 1;
 
WHILE @i<= @max
BEGIN
	INSERT dbo.nombre SELECT @i
	SET @i += 1
END
 
CREATE FUNCTION dbo.SplitStringToInt
	(
		@string AS VARCHAR(max)
	)
RETURNS TABLE
AS
	RETURN
		SELECT	CAST(SUBSTRING(@string, nombre, CHARINDEX(',', @string + ',', nombre) - nombre) AS int) AS element
		FROM	dbo.nombre
		WHERE	nombre<= LEN(@string) + 1
		AND	SUBSTRING(',' + @string, nombre, 1) = ','
GO
@++
amednagh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2011, 18h45   #8
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
A nico:

Citation:
je precise que je travail sur sql server 2005
vous devez donc ignorer les TVP.
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h26.


 
 
 
 
Partenaires

Hébergement Web