Hallo,
ist es möglich, die werte von IN() per Parameter zu übergeben, wobei natürlich mehr als nur ein Wert übergeben werden soll.
Beispiel:
SELECT * FROM tabelle WHERE spalte IN (@paramter)
soll zu
SELECT * FROM tabelle WHERE spalte IN (1,2,3,4,5)
werden
verwendetes Datenbanksystem: Sql Server 2008
Martin Bauer - bauer-martin.com
Hallo,
bei IN bleibt dir nichts anderes übrig, als dynamisches Sql zu verwenden. Das dann in einer SP und anschließend per EXEC(Statement) das Sql ausführen.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Unschön, aber hab das leider befürchtet.
Wäre nicht schlecht, wenn sich das in zukünftigen Versionen mal ändern würde, so dass man dort z. B. ein array bzw. List übergeben könnte.
Martin Bauer - bauer-martin.com
Listen, bzw. Arrays, lassen sich ab dem SQL Server 2005 schon verwenden. Dann in Form von XML oder per TABLE Parameter. Allerdings muss man dann immer noch das eigentliche SQL dynamisch zusammenbauen. Was allerdings wirklich ein wenig unschön ist.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Hmm hab gerade google befragt und da scheints zu funktionieren.. wird nur anders geschrieben
Grüße
hier ein paar anregungen wenn es in .net 2 sein muss:
Passing Arrays to SQL Stored Procedures in C# ASP .NET
How to pass a list of values or array to SQL Server stored procedure?
und für deinen fall ließe sich das sogar recht einfach noch sql-injection-sicher machen.
List<string> myParameterValues = new List<string>();
myParameterValues.Add("asdf1");
myParameterValues.Add("asdf2");
string commaseperated = string.Empty;
int[] count = {1};
myParameterValues.ForEach(param => commaseperated+= ",@P" + count[0]++);
SqlCommand command = new SqlCommand(string.Format("SELECT * FROM tabelle WHERE spalte IN ({0})", commaseperated));
count[0] = 1;
myParameterValues.ForEach(param => command.Parameters.AddWithValue(string.Format("@p{0}",count[0]++),param));
lässt sich sicher noch besser und einfacher machen aber als anregung ist das ausreichend 😉
Nicht direkt 100% auf dieses Thema, aber ähnliches Problem besteht, wenn du alternativ auf NULL oder einen Wert prüfen willst.
select * from Clients where Country = 'D'
oder
select * from Clients where Country is null
kriegt man leider auch nicht mit Parametern in den Griff, da einerseits der = Operator verwendet werden muss bei Wertprüfung und den IS Operator bei NULL Prüfung...
Auch unschön :evil:
Hi
Grundsätzlich sollte man mit IN-Statements immer etwas vorsichtig sein. Die sind erstens nicht besonders performant und erzeugen immer wieder einen neuen Execution Plan.
Es gibt hier mehrere Wege das anders zu realisieren. Ich bevorzuge dabei die folgenden beiden:
Separierte Liste mit serverseitigem Split
Die Werte als Komma/Tab/... (ich nehme meistens Tab) separate Liste an den Server schicken. Dort die Werte über eine String-Split Funktion in eine Temp-Table oder Tabellenvariable auflösen und über ein "WHERE xyz IN (SELECT Item FROM @SplitValues)" anhängen.
Table-Valued Parametesr
Seit SQL Server 2008 gibt's Table-Valued Parameters. Hiermit ist es möglich direkt eine Collection von Werten an den SQL Server zu übergeben. Dort dann ebenfalls wieder über "WHERE xyz IN (SELECT Item FROM @tvp)" vereinen.
Beide Wege sind sicher vor SQL Injection, sehr performant und erzielen eine Cached Plan Reusage.
Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+
Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
Hi,
kann mich Florian nur anschließen, die erste Variante (TVF SplitIDs aufm Server) wird bei uns auch eingesetzt, rennt bestens.
Hoffe bald gibts bei uns mal nen Update aufn 2008er 😃
Gruß
DevHB