我希望将理论上无限数量的ID作为一个变量传递给存储过程,并让它返回所有匹配的记录。当使用list和IN语句时我得到一个错误,因为ProviderID
数据类型是INT,并且它将我的列表视为字符串。
DECLARE @ProviderList varchar(max)
SET @ProviderList = '1001,1002'
SELECT *
FROM tblProviders
WHERE ProviderID IN ( @ProviderList )
--Error: Error converting data type varchar to bigint. when used
将ID分隔如下工作......但由于无法知道将同时搜索多少个ID,因此找到不需要的潜在占位符变量会很麻烦。
DECLARE @ProviderOne varchar(max)
SET @ProviderOne = '1001'
DECLARE @ProviderTwo varchar(max)
SET @ProviderTwo = '1002'
SELECT *
FROM tblProviders
WHERE ProviderID IN ( @ProviderOne, @ProviderTwo )
答案 0 :(得分:2)
有两种方法可以做到这一点。一种是分隔字符串,然后将其拆分。由于我不确定您使用的是哪个版本的SQL Server,因此您可以找到Jeff Moden的分隔字符串拆分器here的副本。
然后你可以做类似的事情:
SELECT *
FROM MyTable MT
WHERE MT.MyValues IN (SELECT Item FROM dbo.delimitedSplit8k(@DelimString,',');
另一种方法是使用自定义表值类型。您可以在此处创建表格形式的数据类型。所以,例如:
CREATE TYPE IDs AS TABLE (ID int);
GO
DECLARE @ID IDs;
INSERT INTO @ID
VALUES (1),(2),(3)
SELECT *
FROM MyTable MT
WHERE MT.MyValues IN (SELECT ID FROM @ID);
GO
--Clean up
--DROP TYPE IDs;
如有任何问题,请发表评论。
答案 1 :(得分:1)
最好的方法可能是查询字符串并使用动态SQL。这允许优化器编译查询以实现最佳执行。这种方法是将id列表直接插入到字符串中。当然,如果列表来自用户输入,这可能是一个非常糟糕的主意,因为这种方法会引入SQL注入的风险。
另一种方法是拆分字符串。最新版本的SQL Server(2016+)具有string_split()
(或者您可以非常轻松地在Web上找到UDF):
SELECT p.*
FROM tblProviders p
WHERE p.ProviderID IN (SELECT string_split(@ProviderList, ',') )
答案 2 :(得分:0)
您可以接受输入为csv,然后您可以将csv转换为list并按参数
传递SELECT *
FROM tblProviders
WHERE ProviderID IN (SELECT * FROM dbo.CSVToLIst(@CSV))
CSV列出功能
CREATE FUNCTION dbo.CSVToList (@CSV varchar(3000))
RETURNS @Result TABLE (Value varchar(30))
AS
BEGIN
DECLARE @List TABLE
(
Value varchar(30)
)
DECLARE
@Value varchar(30),
@Pos int
SET @CSV = LTRIM(RTRIM(@CSV))+ ','
SET @Pos = CHARINDEX(',', @CSV, 1)
IF REPLACE(@CSV, ',', '') <> ''
BEGIN
WHILE @Pos > 0
BEGIN
SET @Value = LTRIM(RTRIM(LEFT(@CSV, @Pos - 1)))
IF @Value <> ''
INSERT INTO @List (Value) VALUES (@Value)
SET @CSV = RIGHT(@CSV, LEN(@CSV) - @Pos)
SET @Pos = CHARINDEX(',', @CSV, 1)
END
END
INSERT @Result
SELECT
Value
FROM
@List
RETURN
END
答案 3 :(得分:0)
如果您使用的是SQL Server 2016或更高版本,或者使用Azure SQL,则可以使用JSON:
DECLARE @ProviderList varchar(max)
SET @ProviderList = '[1001,1002]'
SELECT *
FROM tblProviders
WHERE ProviderID IN ( SELECT CAST(p.[Value] AS INT) FROM OPENJSON(@ProviderList) p )
这是最快,最安全的方法
答案 4 :(得分:0)
DECLARE @ProviderList varchar(max)
Declare @sqlstring nvarchar(2000)
SET @ProviderList = '100,200,300'
set @sqlstring = 'SELECT * FROM temptable where Num_Key in (' + @ProviderList + ')'
--select @sqlstring
execute sp_executesql @sqlstring