我在IN SQL语句有一个小问题。我只是想知道有人能帮助我吗?TSQL声明IN
@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.
我在IN SQL语句有一个小问题。我只是想知道有人能帮助我吗?TSQL声明IN
@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.
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。
您正在做的事情对于SQL IN
语句不可行。您无法将字符串传递给它,并期望该字符串被解析。 IN用于特定的硬编码值。
杰森:
首先创建这样
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)
+1:对于表值函数示例 – 2010-12-18 20:47:07
有两种方法可以做到你想在这里做什么。 一个是创建一个'动态sql'查询并执行它,代入IN列表后。
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-的“作为”字段引用基于链接的功能,哪些商店名为's'的列中的拆分值。这可能会因您的字符串分割函数的实现而有所不同
这很好,因为它使用基于集合的方法查询而不是IN子查询,但CROSS JOIN可能有点复杂,所以如果你想保持IN语法,那么下面的应该工作:
SELECT * FROM Nav
WHERE Nav.NavigationId IN
(SELECT CONVERT(int, a.s) AS Value
FROM dbo.StringSplit(@Ids) a
作为一个侧面说明,动态查询不能很好地处理查询优化器,但这不是问题。 – 2010-12-18 20:39:14
@PulsarBlow:“处理得好”是模糊的,而且不正确 - 动态和非动态查询与优化器没有区别。但是'EXEC'已知不会缓存查询计划,而'sp_executesql'确实不会。我建议你阅读关于动态sql的诅咒和祝福的链接。 – 2010-12-18 20:44:21