簡體   English   中英

(@Variable)查詢中的SQL

[英]SQL in (@Variable) query

我有以下代碼,問題是我的變量列表@LocationList本質上是一個csv字符串。 當我使用它作為(@LocationList)中LocationID的一部分時,它表示它不是一個int(LocationID是一個i​​nt)。 如何讓這個csv字符串被teh in子句接受?

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

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

最有效的方法是使用動態SQL,例如rt2800提及(由邁克爾艾倫注射警告)

但是你可以做一個功能:

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發送多值列表時,這非常有用。

我經常有這個要求, 有時 ,如果你很清楚你正在搜索的列[大小/格式/長度],你可以做一種REGEX。

像這樣的東西:

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

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

注意 :PIPE字符用於保護查詢不返回任何包含單個字符的LocationID(例如,“1”)。

這是一個完整的工作示例:

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 + '|%')
declare @querytext Nvarchar(MAX)

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

exec sp_executesql @querytext;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM