SQL Server存储过程与SCOPE_IDENTITY和ADO.NET参数化查询

时间:2012-10-12 18:59:34

标签: asp.net sql-server stored-procedures

我的存储过程应该返回我新创建的行的标识,但不是。

存储过程语法(简而言之):

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中执行该过程时,这可以正常工作 - 插入一个新行并返回其标识。但是,当我从我的网络应用程序执行时,使用下面的代码,我收到错误。

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进行的测试证实)。

我以为我在某处读到当你使用与SQL Server存储过程对话的ADO.NET参数化查询时,范围不是你所期望的那样,因为它实际上使用另一个存储过程来执行你所要求的那个对于。这有什么好处吗?

有什么想法吗?

编辑:使用SELECT CAST(SCOPE_IDENTITY() AS INT)也不起作用。另外:即使我没有将ExecuteScalar的结果赋值为Integer值,我也会收到此错误 - 即使我只是response.write obj_command.ExecuteScalar()

我也会得到同样的错误

2 个答案:

答案 0 :(得分: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在服务器上(我建议)或在客户端执行此操作。

答案 1 :(得分:0)

ExecuteScalar始终返回对象数据类型。所以要从中检索整数值,你必须像这样转换它。

例如

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