2012-04-26 5 views
5

다음 코드가 있습니다. 문제는 내 변수 목록 @LocationList가 본질적으로 csv 문자열이라는 것입니다. 이것을 LocationID (@LocationList)의 어디에서 사용하는지는 int가 아니라고 말합니다 (LocationID는 int 임). 이 csv 문자열을 teh in 절에서 받아 들일 수있는 방법은 무엇입니까?SQL (@Variable) 쿼리

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

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

가능한 중복 - 매개 변수를 전달 "IN"배열 목록에 대한?] (http://stackoverflow.com/questions/537087/sql-server-sp-pass-parameter-for-in-array-list) – Lamak

+0

당신은 [표 값 매개 변수 ] (http://msdn.microsoft.com/en-us/library/bb510489.aspx)를 참조하십시오. 'Select Location from where LocationID in (@LocationList에서 위치 선택) ' –

답변

5

이 작업을 수행하는 가장 효율적인 방법은 rt2800가 (마이클 알렌에 의해 주입 경고와 함께) 언급과 같은 동적 SQL로 당신이 기능 할 수 그러나

:

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 

및 그 중에서 선택하십시오 :

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

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

또는

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

SSRS에서 PROC로 다중 값 목록을 보내려고 할 때 매우 유용합니다.

+0

** 필요한 ** 캐스팅이 필요할 수도 있습니다 ** – SQLMason

+0

아, 좋은 생각 이네요. 고마워요. –

0
declare @querytext Nvarchar(MAX) 

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

exec sp_executesql @querytext; 
+0

이 방법을 강력히 제안하면 SQL 주입에 너무 많은 위험이 있습니다. 일반적으로 exec 메소드에서 벗어나면 위험합니다. –

+0

@MichaelAllen 목록 작성 방법에 따라 다르지만 SQL 삽입과 ** sp_executesql **이 더 좋을 것입니다. 실행 계획을 캐시 할 수도 있기 때문입니다. – SQLMason

1

종종이 요구 사항이 있으며 때때로입니다. [크기/형식/길이]에서 검색하는 열을 잘 알고 있으면 REGEX를 사용할 수 있습니다. 이 같은

뭔가 :

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

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

참고 : 파이프 문자 (예를 들어, '1') 하나의 문자가 포함 된 LocationID를 반환에서 쿼리를 보호하는 데 사용됩니다.

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 + '|%' 

경고 :

여기에 완전한 작동 예입니다! 이 방법은 색인 친화적이지 않습니다! 당신이 활용, 모든 점에서 INDEXES의 사용을 일부 IN (@MyListOfLocation)를 추가 할 싶은 경우에, 당신은 당신의 스크립트를 수정할 수 있습니다

할 일 :

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