【问题标题】:Yet another Conversion failed when converting the varchar value 'n' to data type int将 varchar 值“n”转换为数据类型 int 时,又一次转换失败
【发布时间】:2013-03-25 17:05:37
【问题描述】:

我有以下存储过程:

CREATE PROCEDURE [cafgAddCoreID]
@HoldingName nvarchar (50) = null
@CountStart int = 0,
AS
DECLARE @sql nvarchar (50)
DECLARE @bit nvarchar (200)
BEGIN
    SET @bit = 'MTR1- + CAST ((' + @CountStart + ' + ROW_NUMBER() 
      OVER (ORDER BY [FindNo])) AS NVARCHAR(10))'
    SET @sql = 'INSERT INTO ' + @HoldingName + '([CoreID]) 
      SELECT (' + @bit + ') FROM [DectectoristMetalFinds]'
    EXEC @sql
END    

但是当我跑步时:

EXEC [cafgAddCoreID] 'Table1', 9

我明白了

将 varchar 值 'MTR1- + CAST ((' )转换为数据类型 int 时转换失败。

跑步

INSERT INTO [Table1] ([CoreID])   
SELECT ('MTR1-' + CAST ((0 + ROW_NUMBER() OVER (ORDER BY FindNo)) 
  AS NVARCHAR(10))) AS CoreID FROM [Table2]

有效,所以我知道该方法是正确的,但显然不是在存储过程中。

【问题讨论】:

  • 在执行@sql之前,你调查过它的值吗?
  • 您需要确保MTR1- 被适当数量的撇号包围。此外,heeeeello SQL 注入攻击。
  • 抱歉,我不知道如何检查@sql 的值,因为我是存储过程的新手。
  • 尝试PRINT @sql;,但根据错误,您不会走那么远。您需要将 @CountStart 设置为字符串才能构建字符串。

标签: sql-server stored-procedures


【解决方案1】:

您不能将整数“添加”到字符串中。数据类型优先级将尝试将周围的文字转换为 int。相反,您需要将您的 int 显式更改为字符串:

SET @bit = '''MTR1-'' + CAST ((' + CONVERT(VARCHAR(12), @CountStart) + '...

看起来它仍然无法正确解析,但应该可以让您通过以下方式进一步调查:

PRINT @sql;

代替:

EXEC @sql;

你也可以使用:

EXEC(@sql);

或者更好:

EXEC sp_executesql @sql;

(您可以使用它来参数化 @CountStart 并避免使用一个向量进行 SQL 注入。我会为您编写该版本,但无法从您的问题中分辨出您首先尝试生成的有效 SQL 是什么。 )

您可能还想考虑为@sql 提供超过 50 个字符。只是一个想法。

【讨论】:

  • 我知道有人问过这个问题,但我找不到与我的特定问题相关的答案。我要访问的 sql 是: INSERT INTO [Table1] ([CoreID]) SELECT ('MTR1-' + CAST ((0 + ROW_NUMBER() OVER (ORDER BY FindNo)) AS NVARCHAR(10))) AS CoreID FROM [Table2]
  • 对不起,我尝试将其添加为代码但失败了,我会再试一次。INSERT INTO [Table1] ([CoreID]) SELECT ('MTR1-' + CAST ((0 + ROW_NUMBER() OVER (ORDER BY FindNo)) AS NVARCHAR(10))) AS CoreID FROM [Table2] 这有效。
  • 谢谢@aaron-bertrand。通过打印@sql,我发现了问题。在 MTR 和 @CountStart 的转换周围还不够
猜你喜欢
  • 2011-12-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多