6

次のコードがあります。問題は、変数リスト @LocationList が本質的に csv 文字列であることです。これを where LocationID in (@LocationList) の一部として使用すると、int ではないと表示されます (LocationID は int です)。このcsv文字列を節で受け入れるにはどうすればよいですか?

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

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

3 に答える 3

7

これを行う最も効率的な方法は、rt2800 言及などの動的 SQL を使用することです (Michael Allen によるインジェクション警告付き)。

ただし、関数を作成できます。

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 に複数値リストを送信しようとするときに非常に役立ちます。

于 2012-04-26T12:38:43.600 に答える
1

私はしばしばこの要件を持っています.SOMETIME、[サイズ/フォーマット/長さ]で検索している列をよく知っている場合は、一種のREGEXを実行できます。

このようなもの :

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

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

: PIPE 文字は、クエリが 1 文字 (たとえば、'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 + '|%'

警告!このメソッドはインデックスに適していません!

そのすべてに IN(@MyListOfLocation) を追加したい場合は、INDEXES の使用を活用するために、スクリプトを次のように変更できます。

SELECT MyDATA.* 
FROM   HugeTableWithAnIndexOnLocationID as MyDATA 
WHERE  LocationID in (
      Select LocationID 
      from  Table 
      where @MyListOfLocation like '%|' +  LocationID + '|%')
于 2014-06-12T15:49:26.363 に答える
0
declare @querytext Nvarchar(MAX)

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

exec sp_executesql @querytext;
于 2012-04-26T12:30:55.883 に答える