SQL查询转换nvarchar到数据类型int在存储过程中出错

时间:2015-09-21 04:08:09

标签: sql-server stored-procedures

我有一个问题,我不知道为什么我在存储过程中使用它时会一直收到此错误。

  

转换nvarchar值时转换失败   ' 3,25,26,27,28,33,34'数据类型int。

这是我使用的查询。

@idList nvarchar(max)

@idList='3,25,26,27,28,33,34'

update tSpecScaleValidation set LastTriggeredTime=getdate() where id in (@idList)

但是,当我在不使用存储过程的情况下进行更新时,它的工作正常。

2 个答案:

答案 0 :(得分:0)

因为@idListNVARCHARWHERE子句被评估为 id = '3,25,26,27,28,33,34'。由于idINT并且higher data type precedence而非NVARCHAR'3,25,26,27,28,33,34'会转换为INT,从而导致错误:

  

转换nvarchar值时转换失败   ' 3,25,26,27,28,33,34'数据类型int。

另一种方法是使用动态sql:

declare @sql nvarchar(max) 
set @sql= N'update tSpecScaleValidation set LastTriggeredTime = getdate() where id in (' + @idList + ');'

exec(@sql)

或使用CSV分割器。这是一张取自Aaron Bertrand的article

CREATE FUNCTION dbo.SplitStrings_XML
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN 
   (  
      SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
      FROM 
      ( 
        SELECT x = CONVERT(XML, '<i>' 
          + REPLACE(@List, @Delimiter, '</i><i>') 
          + '</i>').query('.')
      ) AS a CROSS APPLY x.nodes('i') AS y(i)
   );

并在UPDATE声明中使用

update tSpecScaleValidation 
    set LastTriggeredTime=getdate() 
where id in (
    select item
    from dbo.SplitStrings_XML(@idList, ',')
)

答案 1 :(得分:0)

问题是变量@idList='3,25,26,27,28,33,34'整体转换为int。它没有像你想象的那样转换。你不能直接这样做。解决方法是使用动态查询:

declare @sql nvarchar(2000)
set @sql = 'udate tSpecScaleValidation set LastTriggeredTime=getdate() where id in (' + @idList + ')'
exec(@sql)

谨防sql注入!您无法对此查询进行参数化的坏消息,因此如果您从变量@idList的客户端传递一些数据,请务必小心。