定义与IN运算符一起使用的variables(T-SQL)

我有一个使用IN运算符的Transact-SQL查询。 像这样的东西:

select * from myTable where myColumn in (1,2,3,4) 

有没有办法定义一个variables来保存整个列表“(1,2,3,4)”? 我应该如何定义它?

 declare @myList {data type} set @myList = (1,2,3,4) select * from myTable where myColumn in @myList 
 DECLARE @MyList TABLE (Value INT) INSERT INTO @MyList VALUES (1) INSERT INTO @MyList VALUES (2) INSERT INTO @MyList VALUES (3) INSERT INTO @MyList VALUES (4) SELECT * FROM MyTable WHERE MyColumn IN (SELECT Value FROM @MyList) 
 DECLARE @mylist TABLE (Id int) INSERT INTO @mylist SELECT id FROM (VALUES (1),(2),(3),(4),(5)) AS tbl(id) SELECT * FROM Mytable WHERE theColumn IN (select id from @mylist) 

使用这样的function:

 CREATE function [dbo].[list_to_table] (@list varchar(4000)) returns @tab table (item varchar(100)) begin if CHARINDEX(',',@list) = 0 or CHARINDEX(',',@list) is null begin insert into @tab (item) values (@list); return; end declare @c_pos int; declare @n_pos int; declare @l_pos int; set @c_pos = 0; set @n_pos = CHARINDEX(',',@list,@c_pos); while @n_pos > 0 begin insert into @tab (item) values (SUBSTRING(@list,@c_pos+1,@n_pos - @c_pos-1)); set @c_pos = @n_pos; set @l_pos = @n_pos; set @n_pos = CHARINDEX(',',@list,@c_pos+1); end; insert into @tab (item) values (SUBSTRING(@list,@l_pos+1,4000)); return; end; 

而不是使用like,可以使用函数返回的表进行内连接:

 select * from table_1 where id in ('a','b','c') 

 select * from table_1 a inner join [dbo].[list_to_table] ('a,b,c') b on (a.id = b.item) 

在一个没有build立索引的1Mlogging表中,第二个版本占了大约一半的时间。

干杯

有两种方法可以解决TSQL查询的dynamiccsv列表:

1)使用内部select

 SELECT * FROM myTable WHERE myColumn in (SELECT id FROM myIdTable WHERE id > 10) 

2)使用dynamic连接的TSQL

 DECLARE @sql varchar(max) declare @list varchar(256) select @list = '1,2,3' SELECT @sql = 'SELECT * FROM myTable WHERE myColumn in (' + @list + ')' exec sp_executeSQL @sql 

3)可能的第三个选项是表variables。 如果您有SQl Server 2005,则可以使用表variables。 如果您在Sql Server 2008上,甚至可以将整个表variables作为parameter passing给存储过程,并将其用于联接中或作为IN子句中的子查询。

 DECLARE @list TABLE (Id INT) INSERT INTO @list(Id) SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 SELECT * FROM myTable JOIN @list l ON myTable.myColumn = l.Id SELECT * FROM myTable WHERE myColumn IN (SELECT Id FROM @list) 
 DECLARE @myList TABLE (Id BIGINT) INSERT INTO @myList(Id) VALUES (1),(2),(3),(4); select * from myTable where myColumn in(select Id from @myList) 

请注意,对于长列表或生产系统,不build议使用这种方式,因为它可能比简单的IN运算符(如someColumnName in (1,2,3,4) (使用8000+项列表进行testing)

不,没有这种types。 但是有一些select:

  • dynamic生成的查询(sp_executesql)
  • 临时表
  • 表typesvariables(最接近的列表)
  • 创build一个XMLstring,然后将其转换为一个带有XML函数的表格(真是尴尬和迂回,除非你有一个XML开头)

这些都不是很优雅,但这是最好的。

如果你不想使用第二个表,你可以用CAST做一个LIKE比较:

 DECLARE @myList varchar(15) SET @myList = ',1,2,3,4,' SELECT * FROM myTable WHERE @myList LIKE '%,' + CAST(myColumn AS varchar(15)) + ',%' 

如果你正在比较的字段已经是一个string,那么你将不需要CAST。

围绕列匹配和逗号中的每个唯一值将确保完全匹配。 否则,在包含',4,2,15'的列表中可以find值1

我想你将不得不声明一个string,然后执行该SQLstring。

看看sp_ExecuteSQL

 DECLARE @StatusList varchar(MAX); SET @StatusList='1,2,3,4'; DECLARE @Status SYS_INTEGERS; INSERT INTO @Status SELECT Value FROM dbo.SYS_SPLITTOINTEGERS_FN(@StatusList, ','); SELECT Value From @Status;