SQL Server 过程声明一个列表
Posted
技术标签:
【中文标题】SQL Server 过程声明一个列表【英文标题】:SQL Server procedure declare a list 【发布时间】:2014-01-16 11:25:37 【问题描述】:我的 SQL 代码相当简单。我正在尝试从这样的数据库中选择一些数据:
SELECT * FROM DBTable
WHERE id IN (1,2,5,7,10)
我想知道如何在选择之前声明列表(在变量、列表、数组或其他东西中)并且在选择内部只使用变量名,如下所示:
VAR myList = "(1,2,5,7,10)"
SELECT * FROM DBTable
WHERE id IN myList
【问题讨论】:
你使用的是哪个 sql server 版本? 我正在使用 Microsoft SQL Server 2008 R2 ***.com/questions/6369/…的可能重复 ^不相关的 IMO,尽管肯定存在重复。 mysql but might be helpful 【参考方案1】:您可以像这样将变量声明为临时表:
declare @myList table (Id int)
这意味着您可以使用insert
语句来填充值:
insert into @myList values (1), (2), (5), (7), (10)
那么您的select
语句可以使用in
语句:
select * from DBTable
where id in (select Id from @myList)
或者你可以像这样加入临时表:
select *
from DBTable d
join @myList t on t.Id = d.Id
如果你经常做这样的事情,那么你可以考虑定义一个user-defined table type,这样你就可以像这样声明你的变量:
declare @myList dbo.MyTableType
【讨论】:
谢谢!我最后使用了你的解决方案:)【参考方案2】:这对于普通查询是不可能的,因为in
子句需要单独的值,而不是包含逗号分隔列表的单个值。一种解决方案是动态查询
declare @myList varchar(100)
set @myList = '1,2,5,7,10'
exec('select * from DBTable where id IN (' + @myList + ')')
【讨论】:
谢谢!我正要问你如何正确声明它!我试试这个。【参考方案3】:您可以将传递的值列表转换为表值参数,然后针对该列表进行选择
DECLARE @list NVARCHAR(MAX)
SET @list = '1,2,5,7,10';
DECLARE @pos INT
DECLARE @nextpos INT
DECLARE @valuelen INT
DECLARE @tbl TABLE (number int NOT NULL)
SELECT @pos = 0, @nextpos = 1;
WHILE @nextpos > 0
BEGIN
SELECT @nextpos = charindex(',', @list, @pos + 1)
SELECT @valuelen = CASE WHEN @nextpos > 0
THEN @nextpos
ELSE len(@list) + 1
END - @pos - 1
INSERT @tbl (number)
VALUES (convert(int, substring(@list, @pos + 1, @valuelen)))
SELECT @pos = @nextpos;
END
SELECT * FROM DBTable WHERE id IN (SELECT number FROM @tbl);
在此示例中,传入 '1,2,5,7,10' 的字符串由逗号分隔,每个值都作为新行添加到 @tbl
表变量中。然后可以使用标准 SQL 来选择它。
如果您打算重用此功能,您可以进一步将其转换为函数。
【讨论】:
【参考方案4】:我一直发现在这种情况下,根据列表反转测试更容易。比如……
SELECT
field0, field1, field2
FROM
my_table
WHERE
',' + @mysearchlist + ',' LIKE '%,' + CAST(field3 AS VARCHAR) + ',%'
这意味着您要查找的值不需要复杂的混搭。
例如,如果我们的列表是 ('1,2,3')
,那么我们在列表的开头和结尾添加一个逗号,如下所示:',' + @mysearchlist + ','
。
我们也对要查找的字段值执行相同操作并添加通配符:'%,' + CAST(field3 AS VARCHAR) + ',%'
(注意%
和,
字符)。
最后我们使用LIKE
运算符测试这两者:',' + @mysearchlist + ',' LIKE '%,' + CAST(field3 AS VARCHAR) + ',%'
。
【讨论】:
【参考方案5】:如果你想输入逗号分隔的字符串作为输入并在查询中应用,那么你可以使函数像:
create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end;
你可以像这样使用它:
Declare @Values VARCHAR(MAX);
set @Values ='1,2,5,7,10';
Select * from DBTable
Where id in (select items from [dbo].[Split] (@Values, ',') )
或者,如果您没有逗号分隔的字符串作为输入,您可以尝试Table variable
OR TableType
或 Temp table
喜欢:INSERT using LIST into Stored Procedure
【讨论】:
这适用于所有类型吗?您不需要将函数的输出转换为INT
吗?
@Westie,比较的类型必须相同。因此,如果 dbtable 中的 id 是 int 类型,那么是的,它需要强制转换。【参考方案6】:
@Peter Monks 的替代品。
如果'in'语句中的数字很小且固定。
DECLARE @var1 varchar(30), @var2 varchar(30), @var3 varchar(30);
SET @var1 = 'james';
SET @var2 = 'same';
SET @var3 = 'dogcat';
Select * FROM Database Where x in (@var1,@var2,@var3);
【讨论】:
以上是关于SQL Server 过程声明一个列表的主要内容,如果未能解决你的问题,请参考以下文章