我有以下代码,问题是我的变量列表@LocationList本质上是一个csv字符串。当我使用它作为(@LocationList)中LocationID的一部分时,它表示它不是一个int(LocationID是一个int)。如何让这个csv字符串被teh in子句接受?
Declare @LocationList varchar(1000)
Set @LocationList = '1,32'
select Locations from table where Where LocationID in (@LocationList)
答案 0 :(得分:6)
最有效的方法是使用动态SQL,例如rt2800提及(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) )
OR
SELECT Locations
FROM table loc
INNER JOIN dbo.CSVStringsToTable_fn(@LocationList) list
ON list.value = loc.LocationID
当您尝试从SSRS向PROC发送多值列表时,这非常有用。
答案 1 :(得分:1)
我经常有这个要求,而有时,如果你很清楚你要搜索的列[大小/格式/长度],你可以做一种REGEX。
这样的事情:
DECLARE @MyListOfLocation varchar(255)
set @MyListOfLocation = '|1|32|36|24|3|'
Select LocationID
from Table
where @MyListOfLocation like '%|' + LocationID + '|%'
注意:PIPE字符用于保护查询不返回包含单个字符的任何LocationID(例如&#39; 1&#39;)。
这是一个完整的工作示例:
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 + '|%')
答案 2 :(得分:0)
declare @querytext Nvarchar(MAX)
set @querytext = 'select Locations from table where Where LocationID in (' + @LocationList + ');';
exec sp_executesql @querytext;