2012-10-12 46 views
1

我的存儲過程應該返回我新創建的行的標識,但它不是。使用SCOPE_IDENTITY和ADO.NET參數化查詢的SQL Server存儲過程

存儲過程語法(簡單地說):

Alter Procedure dbo.udsp_insert_record 
    @record_title VARCHAR(100) 
AS 
BEGIN 
    INSERT INTO tbl_records (RecordTitle) VALUES (@record_title) 
    SELECT SCOPE_IDENTITY() 
END 

這是當我執行在SQL Server Management Studio中的程序預期工作 - 一個新的行插入,並返回其身份。但是,當我從我的web應用程序執行時,使用下面的代碼,我得到一個錯誤。

dim obj_command as New SqlCommand("udsp_insert_record",obj_connection) 
obj_command.CommandType = CommandType.StoredProcedure 
obj_command.Parameters.Add("@record_title",SqlDbType.VarChar).Value = "just testing" 
dim n_new_record_id as Integer = obj_command.ExecuteScalar() 
obj_command.Dispose() 'etc., etc. 

在運行此,我得到的錯誤

輸入字符串沒有在與ExecuteScalar命令行了正確的格式

我的解釋是,SQL Server沒有返回一個整數值 - 它必須返回一個對象或DBNull或其他東西。

但這是爲什麼呢? INSERTSELECT SCOPE_IDENTITY()發生在相同的範圍內,所以SQL Server回傳的身份值必須有效(通過我通過SQL Server Management Studio進行的測試證實)。

我以爲我讀了一些地方,當你使用ADO.NET與SQL Server存儲過程交談的參數化查詢時,範圍不是你期望的範圍,因爲它實際上使用另一個存儲過程來執行一個你要求。這有什麼好處?

任何想法?

編輯:使用SELECT CAST(SCOPE_IDENTITY() AS INT)也不起作用。另外:即使我沒有將ExecuteScalar的結果賦值爲Integer值,我也會得到這個錯誤 - 即使我只是做了同樣的錯誤response.write obj_command.ExecuteScalar()

回答

0

ExecuteScaler總是返回一個對象數據類型。所以要檢索整數值,你必須像這樣轉換它。

例如。

object id=cmd.ExecuteScaler(........... 
if(id != null) 
{ 
int newId=Convert.ToInt32(id); 
} 
+0

改變你的代碼來檢查'nulls'或使用'Int32.TryParse',你的答案是不是比OP不同(原海報)做 –

+0

誰是OP在這裏? –

1

我會努力改變存儲過程一點點:

Alter Procedure dbo.udsp_insert_record 
    @record_title VARCHAR(100) 
AS 
BEGIN 
    INSERT INTO tbl_records (RecordTitle) VALUES (@record_title) 
    SELECT CAST(SCOPE_IDENTITY() AS INT) 
END 

從我記得,在SCOPE_IDENTITY()是小數類型的,這樣就可以不那麼容易將其轉換爲int。您可以在服務器上(如我建議的)或在客戶端上執行此操作,將ExecuteScalar轉換爲Decimal

+0

我已經嘗試了CAST方法(和CONVERT) - 同樣的錯誤。而且這個語法(沒有CAST)可以在同一臺服務器上的許多其他存儲過程中完美地工作。另外,我已經編輯我原來的職位,以反映的事實,我得到即使我不分配標量的結果爲整數值這個錯誤 - 我得到同樣的錯誤,即使我只是做'的Response.Write obj_command。ExecuteScalar()' – Octavient

+0

唯一可能的解釋就是你的表的主鍵不是整型。檢查你的表格定義。 –

+0

好主意,@Wiktor Zychla。但它絕對是一個INT列。還有主鍵,身份增量= 1等等。 – Octavient

相關問題