Laden...

Parameter und IN()

Erstellt von gX|progs vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.411 Views
G
gX|progs Themenstarter:in
146 Beiträge seit 2006
vor 14 Jahren
Parameter und IN()

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

3.511 Beiträge seit 2005
vor 14 Jahren

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)

G
gX|progs Themenstarter:in
146 Beiträge seit 2006
vor 14 Jahren

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

3.511 Beiträge seit 2005
vor 14 Jahren

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)

849 Beiträge seit 2006
vor 14 Jahren

Hmm hab gerade google befragt und da scheints zu funktionieren.. wird nur anders geschrieben

In Statement

Grüße

Gelöschter Account
vor 14 Jahren

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 😉

J
1.114 Beiträge seit 2007
vor 14 Jahren

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:

1.564 Beiträge seit 2007
vor 14 Jahren

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ß.

D
211 Beiträge seit 2006
vor 14 Jahren

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