2012-04-26 40 views
5

Aşağıdaki kod var, sorun, değişken listesi @LocationList aslında bir csv dizesi olmasıdır. Bunu, LocationID'de (LocationList) LocationID'nin bir parçası olarak kullandığımda, onun int (LocationID bir int) olduğunu belirtir. Bu csv dizgisini, yan tümce tarafından kabul edilmek için nasıl alabilirim?SQL in (@ Variable) sorgu

Declare @LocationList varchar(1000) 
Set @LocationList = '1,32' 

select Locations from table where Where LocationID in (@LocationList) 
+1

olası yinelenen - parametresini geçirin "IN" dizi listesi için?] (http://stackoverflow.com/questions/537087/sql-server-sp-pass-parameter-for-in-array-list) – Lamak

+0

Bir [Tablo Değeri Parametresi kullanmayı düşündünüz mü? ] (http://msdn.microsoft.com/en-us/library/bb510489.aspx) yerine. Bunu yapar. 'Bulunduğunuz yerdeki Tablolar'ı seçin. (Konumdan @LocationList'den Konum Seçiniz) –

cevap

5

Bunu yapmanın en etkili yolu rt2800 (Michael Allen tarafından enjeksiyon uyarılarla) bahseder gibi Dinamik SQL ile size bir işlev yapabilir Ancak

:

ALTER FUNCTION [dbo].[CSVStringsToTable_fn] (@array VARCHAR(8000)) 
RETURNS @Table TABLE (value VARCHAR(100)) 
AS 
    BEGIN 
     DECLARE @separator_position INTEGER, 
      @array_value VARCHAR(8000) 

     SET @array = @array + ',' 

     WHILE PATINDEX('%,%', @array) <> 0 
      BEGIN 
       SELECT @separator_position = PATINDEX('%,%', @array) 
       SELECT @array_value = LEFT(@array, @separator_position - 1) 

       INSERT @Table 
       VALUES (@array_value) 

       SELECT @array = STUFF(@array, 1, @separator_position, '') 
      END 
     RETURN 
    END 

ve onu seçin:

DECLARE @LocationList VARCHAR(1000) 
SET @LocationList = '1,32' 

SELECT Locations 
FROM table 
WHERE LocationID IN (SELECT * 
          FROM  dbo.CSVStringsToTable_fn(@LocationList)) 

VEYA bir PROC SSRS dan çok değer listesi göndermeye çalışırken son derece yararlıdır

SELECT Locations 
FROM table loc 
     INNER JOIN dbo.CSVStringsToTable_fn(@LocationList) list 
      ON list.value = loc.LocationID 

.

+0

Lütfen dikkat edin, ** gerek duyulduğunda gerek duyduğunuz – SQLMason

+0

Ah bu iyi bir fikir, teşekkür ederim –

0
declare @querytext Nvarchar(MAX) 

set @querytext = 'select Locations from table where Where LocationID in (' + @LocationList + ');'; 

exec sp_executesql @querytext; 
+0

Bu yaklaşımı şiddetle tavsiye edin, sql enjeksiyonu için çok fazla risk. Genel olarak exec yönteminden uzak durun, bu çok tehlikeli. –

+0

@MichaelAllen Listenizin nasıl oluşturulduğuna bağlı olarak değişir, ancak SQL enjeksiyonu hakkında haklısınız ve ** sp_executesql ** daha iyi olurdu - çünkü uygulama planını önbelleğe alabilir. – SQLMason

1

Sık sık bu gereksinimi ve SOMETIME var, [size boyut/biçim/uzunluk] üzerinde aradığınız sütunu çok iyi biliyorsanız, bir çeşit REGEX yapabilirsiniz. Böyle

şey:

DECLARE @MyListOfLocation varchar(255) 
    set @MyListOfLocation = '|1|32|36|24|3|' 

    Select LocationID 
    from Table 
    where @MyListOfLocation like '%|' + LocationID + '|%' 

NOT: BORU karakteri (örneğin, '1') tek bir karakter içeren herhangi LocationID döndürmesini sorguyu korumak için kullanılır.

DECLARE @MyListOfLocation varchar(255) 
set @MyListOfLocation = '|1|11|21|' 

SELECT LocationName 
FROM (
     select '1' as LocationID, 'My Location 1' as LocationName 
     union all 
     select '11' as LocationID, 'My Location 11' as LocationName 
     union all 
     select '12' as LocationID, 'My Location 12' as LocationName 
     union all 
     select '13' as LocationID, 'My Location 13' as LocationName 
     union all 
     select '21' as LocationID, 'My Location 21' as LocationName 
    ) as MySub 
where @MyListOfLocation like '%|' + LocationID + '|%' 

UYARI:

İşte tam çalışma örnektir! Bu yöntem Dizin dostu değil! Eğer kaldıraç, tüm bu içinde İNDEKSLER kullanımını bazı IN (@MyListOfLocation) eklerim istiyorsanız, sizin komut dosyasını

yapmalı:

SELECT MyDATA.* 
FROM HugeTableWithAnIndexOnLocationID as MyDATA 
WHERE LocationID in (
     Select LocationID 
     from Table 
     where @MyListOfLocation like '%|' + LocationID + '|%') 
[SQL Server SP