2013-03-25 103 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

相關問題