2014-01-16 6 views
19

Mein SQL-Code ist ziemlich einfach. Ich versuche, einige Daten aus einer Datenbank wie folgt zu wählen:SQL Server-Prozedur deklarieren Sie eine Liste

SELECT * FROM DBTable 
WHERE id IN (1,2,5,7,10) 

Ich möchte wissen, wie Sie die Liste vor dem Wählen zu erklären (in einer Variablen, Liste, ein Array oder etwas) und innerhalb der Auswahl nur verwenden Sie die Variablennamen, etwa wie folgt:

VAR myList = "(1,2,5,7,10)" 
SELECT * FROM DBTable 
WHERE id IN myList 
+1

Welche SQL-Server-Version verwenden Sie? –

+0

Ich bin mit Microsoft SQL Server 2008 R2 –

+1

Mögliches Duplikat http://stackoverflow.com/questions/6369/how-to-pass-a-comma-separated-list-to-a-stored-procedure – Paul

Antwort

37

Sie könnten eine Variable als eine temporäre Tabelle wie folgt erklären:

declare @myList table (Id int) 

Was bedeutet, dass Sie die insert Anweisung kann es mit Werten füllen:

insert into @myList values (1), (2), (5), (7), (10) 

Dann kann Ihre select Anweisung entweder die in Anweisung verwenden:

select * from DBTable 
where id in (select Id from @myList) 

Oder Sie auf die temporäre Tabelle wie folgt anschließen konnte:

select * 
from DBTable d 
join @myList t on t.Id = d.Id 

Und wenn Sie so etwas wie dies viel tun, dann könnte man erwägen, einen user-defined table type definieren, so können Sie dann Ihre Variable wie folgt erklären:

declare @myList dbo.MyTableType 
+0

Danke! Ich habe deine Lösung am Ende benutzt :) –

6

das ist nicht möglich, mit einer normalen Abfrage ist, da die in Klausel separate Werte benötigt und nicht ein einzelner Wert eine durch Kommata getrennte Liste enthält. Eine Lösung wäre eine dynamische Abfrage

declare @myList varchar(100) 
set @myList = '(1,2,5,7,10)' 
exec('select * from DBTable where id IN ' + @myList) 
+0

Vielen Dank! Ich wollte dich gerade fragen, wie ich es korrekt deklariere! Ich werde es versuchen. –

0

Sie können die Liste der übergebenen Werte in eine Tabelle Wertparameter konvertieren und wählen Sie dann mit dieser Liste

DECLARE @list NVARCHAR(MAX) 
SET @list = '1,2,5,7,10'; 

DECLARE @pos INT 
DECLARE @nextpos INT 
DECLARE @valuelen INT 
DECLARE @tbl TABLE (number int NOT NULL) 

SELECT @pos = 0, @nextpos = 1; 

WHILE @nextpos > 0 
BEGIN 
    SELECT @nextpos = charindex(',', @list, @pos + 1) 
    SELECT @valuelen = CASE WHEN @nextpos > 0 
          THEN @nextpos 
          ELSE len(@list) + 1 
         END - @pos - 1 
    INSERT @tbl (number) 
     VALUES (convert(int, substring(@list, @pos + 1, @valuelen))) 
    SELECT @pos = @nextpos; 
END 

SELECT * FROM DBTable WHERE id IN (SELECT number FROM @tbl); 

In diesem Beispiel wird die Zeichenkette übergeben ‚1,2,5,7,10‘ aufgespalten durch die Kommas und jeder Wert wird als eine neue Zeile in der Tabelle @tbl Variable hinzugefügt. Dies kann dann gegen die Verwendung von Standard-SQL ausgewählt werden.

Wenn Sie diese Funktionalität wiederverwenden möchten, könnten Sie weiter gehen und diese in eine Funktion konvertieren.

0

Wenn Sie eingeben möchten Komma Zeichenfolge getrennt als Eingabe in Abfrage gelten in & dass dann können Sie machen Funktion wie:

create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))  
    returns @temptable TABLE (items varchar(MAX))  
    as  
    begin  
     declare @idx int  
     declare @slice varchar(8000)  

     select @idx = 1  
      if len(@String)<1 or @String is null return  

     while @idx!= 0  
     begin  
      set @idx = charindex(@Delimiter,@String)  
      if @idx!=0  
       set @slice = left(@String,@idx - 1)  
      else  
       set @slice = @String  

      if(len(@slice)>0) 
       insert into @temptable(Items) values(@slice)  

      set @String = right(@String,len(@String) - @idx)  
      if len(@String) = 0 break  
     end 
    return 
    end; 

können Sie es gerne verwenden:

Declare @Values VARCHAR(MAX); 

set @Values ='1,2,5,7,10'; 
Select * from DBTable 
    Where id in (select items from [dbo].[Split] (@Values, ',')) 

Alternativ, wenn Sie Haben Sie keine Komma-getrennte Zeichenfolge als Eingabe, können Sie versuchen Table variable ODER TableType Oder Temp table wie: INSERT using LIST into Stored Procedure

+0

Funktioniert das für alle Typen? Müssen Sie Ihre Ausgabe nicht von der Funktion auf "INT" umwandeln? – Paul

+0

@Westie, Vergleich muss in den gleichen Typen sein. Wenn id in dbtable den Typ int hat, dann ja, muss es umgesetzt werden. –

1

Ich habe es immer einfacher gefunden, den Test in Situationen wie dieser gegen die Liste zu invertieren. Zum Beispiel...

SELECT 
    field0, field1, field2 
FROM 
    my_table 
WHERE 
    ',' + @mysearchlist + ',' LIKE '%,' + CAST(field3 AS VARCHAR) + ',%' 

Das bedeutet, dass es keine komplizierten Mischmasch für die Werte, die Sie suchen erforderlich ist.

Als Beispiel, wenn unsere Liste ('1,2,3') war, dann fügen wir ein Komma zu Beginn und am Ende unserer Liste wie folgt: ',' + @mysearchlist + ','.

Wir machen das gleiche für den Feldwert, den wir suchen und fügen Wildcards hinzu: '%,' + CAST(field3 AS VARCHAR) + ',%' (beachten Sie die % und die , Zeichen).

Schließlich testen wir die beiden mit dem LIKE Operator: .

Verwandte Themen