TSQL声明IN

时间:2010-12-18 20:28:37

标签: sql sql-server tsql

我对IN SQL语句有一个小问题。我只是想知道是否有人可以帮助我?

@Ids = "1,2,3,4,5"

SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (CONVERT(VARCHAR,@Ids))

这回来时会出现以下错误,我相信这很简单!

Conversion failed when converting the varchar value '1,' to data type int.

4 个答案:

答案 0 :(得分:4)

SQL IN子句不接受单个变量来表示值列表 - 没有数据库,而不使用动态SQL。否则,您可以use a Table Valued Function(SQL Server 2000+)将值从列表中拉出来。将它们作为可以加入的表格返回。

动态SQL示例:

EXEC('SELECT * 
        FROM Nav 
       WHERE NavigationID IN ('+ @Ids +')')

我建议在SQL Server上使用动态SQL之前阅读The curse and blessings of dynamic SQL

答案 1 :(得分:1)

詹森:

首先创建一个像这样的函数

Create     FUNCTION [dbo].[ftDelimitedAsTable](@dlm char, @string varchar(8000))
RETURNS 
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
declare @dlm  char, @string varchar(1000)
set @dlm=','; set @string='t1,t2,t3';
-- tHIS FUNCION RETUNRS IN THE ASCENDING ORDER
-- 19TH Apr 06
------------------------------------------------------------------------*/
--declare
    @table_var TABLE 
    (id int identity(1,1),
        r varchar(1000) 
     )
AS
BEGIN
    declare @n int,@i int
    set @n=dbo.fnCountChars(@dlm,@string)+1
    SET @I =1
    while @I <= @N
        begin
            insert @table_var
                select dbo.fsDelimitedString(@dlm,@string,@i)
            set @I= @I+1

        end
    if @n =1 insert @TABLE_VAR VALUES(@STRING)
    delete  from @table_var where r=''
    return
END

然后

set quoted_identifier off
declare @ids varchar(max)
select @Ids = "1,2,3,4,5"
declare @nav table ( navigationid int identity(1,1),theother bigint)
insert @nav(theother) select 10 union select 11 union select 15
SELECT * FROM @Nav WHERE CONVERT(VARCHAR,NavigationID) IN (select id from dbo.ftDelimitedAsTable(',',@Ids))

select * from dbo.ftDelimitedAsTable(',',@Ids)

答案 2 :(得分:0)

使用SQL IN语句无法执行的操作。您不能将字符串传递给它并期望解析该字符串。 IN用于特定的硬编码值。

答案 3 :(得分:0)

有两种方法可以做你想做的事情。 一种是在替换IN列表后创建一个“动态sql”查询并执行它。

DECLARE @query varchar(max);
SET @query = 'SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (' + @Ids + ')'
exec (@query)

这会产生性能影响和其他并发症。一般来说,我会尽量避免它。

另一种方法是使用用户定义函数(UDF)将字符串拆分为其组成部分,然后对其进行查询。 有一篇文章详细介绍了如何创建该函数here

一旦该功能存在,加入它就很简单

SELECT * FROM Nav
CROSS APPLY dbo.StringSplit(@Ids) a
WHERE a.s = CONVERT(varchar, Nav.NavigationId)

NB-'a.s'字段引用基于链接函数,该函数将拆分值存储在名为“s”的列中。根据字符串拆分功能的实现,这可能会有所不同

这很好,因为它使用基于集合的方法来查询而不是IN子查询,但CROSS JOIN目前可能有点复杂,所以如果你想维护IN语法,那么下面的代码应该有效:

SELECT * FROM Nav
WHERE Nav.NavigationId IN
    (SELECT CONVERT(int, a.s) AS Value
    FROM dbo.StringSplit(@Ids) a