为什么SCOPE_IDENTITY()返回-1?

时间:2016-07-13 14:45:43

标签: c# sql sql-server

我写了这个存储过程:

ALTER PROCEDURE [cairs].[sp_SaveR]
    -- Add the parameters for the stored procedure here
@fname  nvarchar(50),
@lname  nvarchar(50),
@mname  nchar(10),
@sigDate    date        
AS
BEGIN
    SET NOCOUNT ON;
    insert into tUser
(fname,
lname,
mname,
sigDate
 )
values
(
@fname,
@lname,
@mname,
@sigDate)

select SCOPE_IDENTITY()

END

这是我用来连接它的c#代码:

try
{
    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            conn.Open();

            cmd.CommandText = "sp_SaveR";                                           
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@fname", fName));
            cmd.Parameters.Add(new SqlParameter("@lname", lName));
            cmd.Parameters.Add(new SqlParameter("@mname", mName));                       
            cmd.Parameters.Add(new SqlParameter("@sigDate", sigDate));

            int userID =  (int)cmd.ExecuteNonQuery();
        }
    }
}
catch (Exception ex)
{
    throw(ex);
}

即使记录已成功插入数据库表,我的userID也始终返回-1。为什么会这样?

3 个答案:

答案 0 :(得分:3)

ExecuteNonQuery会丢弃结果集。它返回的数字通常是受影响的行数,但它并不是你真正可以依赖的东西。在您的情况下,它返回-1,因为您正在执行存储过程,如果您内联SQL,它将返回1.

您想要使用ExecuteScalar,它会读取第一个结果集中第一行的第一列。

答案 1 :(得分:0)

这是按设计工作的。返回值是已修改行的数量。如果您正在调用存储过程或选择数据,则该值将为-1。

来自MSDN ...

SqlCommand.ExecuteNonQuery

  

对于UPDATE,INSERT和DELETE语句,返回值为   受命令影响的行数。当a上存在触发器时   正在插入或更新的表,返回值包括数字   受插入或更新操作影响的行数和数字   受触发器或触发器影响的行数。对于所有其他类型的   语句,返回值为-1。如果发生回滚,则返回   值也是-1。

答案 2 :(得分:0)

您应该使用output参数来检索ID,如下所示。

ALTER PROCEDURE [cairs].[sp_SaveR]
-- Add the parameters for the stored procedure here
@fname  nvarchar(50),
@lname  nvarchar(50),
@mname  nchar(10),
@sigDate    date,
@NewId int OUTPUT        
AS
BEGIN
SET NOCOUNT ON;
insert into tUser
(fname,
lname,
mname,
sigDate
)
values
(
@fname,
@lname,
@mname,
@sigDate)

select @NewId = SCOPE_IDENTITY()

END

在C#中:

try
{
    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            conn.Open();

            cmd.CommandText = "sp_SaveR";                                           
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@fname", fName));
            cmd.Parameters.Add(new SqlParameter("@lname", lName));
            cmd.Parameters.Add(new SqlParameter("@mname", mName));                       
            cmd.Parameters.Add(new SqlParameter("@sigDate", sigDate));
            cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output;

            cmd.ExecuteNonQuery();
            int userId = Convert.ToInt32(cmd.Parameters["@NewId"].Value);
        }
    }
}
catch (Exception ex)
{
    throw(ex);
}