1

我的存储过程应该返回我新创建的行的标识,但事实并非如此。

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

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 没有返回一个整数值——它必须返回一个对象、aDBNull或其他东西。

但这是为什么呢?和发生在同一范围内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()

4

2 回答 2

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。您可以在服务器上(正如我建议的那样)或在客户端上执行此操作,方法是ExecuteScalarDecimal.

于 2012-10-12T19:13:03.283 回答
0

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

例如。

object id=cmd.ExecuteScaler(...........
if(id != null)
{   
 int newId=Convert.ToInt32(id);
}
于 2012-10-12T19:04:16.997 回答