2013-03-25 109 views
0

我有以下存储过程:另一个转换转换为varchar值 'N' 为int数据类型时失败

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] 

的作品,所以我知道的方法是正确的,但显然不是在存储过程。

+1

您是否在执行它之前调查过'@ sql'的值? – bendataclear 2013-03-25 17:07:16

+0

您需要确保'MTR1-'被适当数量的撇号包围。此外,heeeeello SQL注入攻击。 – LittleBobbyTables 2013-03-25 17:08:22

+0

问了这么多次......转换nvarchar值'SELECT \ * FROM'时转换失败的可能重复(http://stackoverflow.com/questions/7683353/conversion-failed-when-converting-the-nvarchar- value-select-from) – 2013-03-25 17:12:18

回答

3

你不能“添加”一个整数到一个字符串。数据类型优先将尝试将周围的文字转换为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个字符。只是一个想法。

+0

我知道这个问题的种类已经被问到,但是我找不到与我的特定问题有关的答案。我试图得到的SQL是:INSERT INTO [Table1]([CoreID]) SELECT('​​MTR1-'+ CAST((0 + ROW_NUMBER()OVER(ORDER BY FindNo)) AS NVARCHAR(10)) )作为CoreID从[表2] – 2013-03-25 17:18:52

+0

对不起,我试图添加它作为代码,但失败了,我会再试一次.'INSERT INTO [表1]([CoreID]) SELECT('​​MTR1-'+ CAST((0 + ROW_NUMBER()OVER(ORDER BY FindNo)) AS NVARCHAR(10)))AS CoreID FROM [Table2]'This works。 – 2013-03-25 17:21:20

+0

谢谢@ aaron-bertrand。通过打印'@ sql',我发现问题所在。 “在地铁周围”以及“@ CountStart”的转换是不够的 – 2013-03-25 17:28:26

相关问题