SQL Server过程声明一个列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server过程声明一个列表相关的知识,希望对你有一定的参考价值。
我的SQL代码非常简单。我正在尝试从数据库中选择一些数据,如下所示:
SELECT * FROM DBTable
WHERE id IN (1,2,5,7,10)
我想知道如何在select之前声明列表(在变量,列表,数组或其他东西中),而select中只使用变量名,如下所示:
VAR myList = "(1,2,5,7,10)"
SELECT * FROM DBTable
WHERE id IN myList
您可以将变量声明为临时表,如下所示:
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
这对于普通查询是不可能的,因为in
子句需要单独的值而不是包含逗号分隔列表的单个值。一种解决方案是动态查询
declare @myList varchar(100)
set @myList = '(1,2,5,7,10)'
exec('select * from DBTable where id IN ' + @myList)
如果你想输入逗号分隔的字符串作为输入并在查询中应用,那么你可以使函数像:
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
或TableType
或Temp table
像:INSERT using LIST into Stored Procedure
在这种情况下,我总是发现在列表中反转测试更容易。例如...
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) + ',%'
。
@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);
您可以将传递的值列表转换为表值参数,然后针对此列表进行选择
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来选择它。
如果您打算重用此功能,可以进一步将其转换为函数。
以上是关于SQL Server过程声明一个列表的主要内容,如果未能解决你的问题,请参考以下文章
使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段