3 Stimmen

Formatierung einer Zeichenkette für eine SQL IN-Klausel

Ich muss eine Zeichenkette formatieren und sie als Parameter für eine SQL IN-Klausel wie folgt übergeben:

Select * from Table Where X In (@param1)

Die Zeichenkette, die als Parameter übergeben wird, sieht folgendermaßen aus:

"Item1, Item2, Item3"

Dies scheint nicht zu funktionieren. Irgendwelche Vorschläge? Danke!

3voto

Nick Craver Punkte 609016

Ich glaube, was Sie tun wollen, finden Sie hier:

Parametrisierung einer SQL IN-Klausel

2voto

Guffa Punkte 663241

Sie können eine Zeichenkette nicht mit dem in Operator und erwarten, dass er ihn analysiert. Es wird einfach die gesamte Zeichenkette mit den Werten vergleichen.

Sie müssten die Abfrage dynamisch erstellen, etwa so:

declare @sql varchar(4000)
set @sql = 'select * from Table where X in (' + @param1 + ')'
exec @sql

Sie müssen die Werte, die Sie im Parameter senden, als Stringliterale formatieren:

"'Item1','Item2','Item3'"

Beachten Sie, dass die String-Werte je nach der von Ihnen verwendeten SQL-Variante korrekt escaped werden müssen. Dies ist sehr wichtig, sonst ist Ihre Abfrage ein gefundenes Fressen für SQL-Injections.

0voto

Jon Punkte 5788

Ich bin nicht sicher, ob dies die beste Antwort ist, aber Sie können den Parameter in einer Funktion analysieren, die eine Tabelle zurückgibt und aus dieser Tabelle als Teil Ihrer In-Klausel auswählen.

Ex.

DECLARE  @param1 varchar(50)
SET @param1 = 'Item1, Item2, Item3'

--CREATE a Table-valued FUNCTION to split param into a table(dbo.f_split_comma_separated_string)

Select * from Table Where X In (SELECT X FROM dbo.f_split_comma_separated_string(@param1))

0voto

KM. Punkte 98297

Siehe meine vorherige Antwort auf diese Frage

Dies ist die beste Quelle:

http://www.sommarskog.se/arrays-in-sql.html

eine Split-Funktion erstellen und sie wie folgt verwenden:

SELECT
    *
    FROM YourTable  y
    INNER JOIN dbo.splitFunction(@Parameter) s ON y.ID=s.Value

Ich bevorzuge den Ansatz der Zahlentabelle

Damit diese Methode funktioniert, müssen Sie die Tabelle einmalig einrichten:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

Sobald die Tabelle Numbers eingerichtet ist, erstellen Sie diese Funktion:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

Sie können jetzt eine CSV-Zeichenfolge einfach in eine Tabelle aufteilen und mit ihr verknüpfen:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

OUTPUT:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

Sie können eine CSV-Zeichenfolge in eine Prozedur einfügen und nur Zeilen für die angegebenen IDs verarbeiten:

SELECT
    y.*
    FROM YourTable y
        INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue

Dabei wird ein Index auf y.ID verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X