我对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.
答案 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