从Sql中选择Scope Identity

时间:2015-07-14 18:42:03

标签: c# sql sql-server

我正在执行Insert查询。我想返回标识元素。我也在使用相同的存储过程。在另一个存储过程内部返回标识元素。

Alter Proc Proc1 
    @name varchar(10),
    @value int
As
Begin
    insert into Table1 
    values (@name, @value)

    return SCOPE_IDENTITY()

C#代码:

我有一种方法每次调用我的数据库,所以我使用

_database.StoredProcedure = "Proc1";
_database.parameter("name","michael");
_database.parameter("value",10);

int id = Convert.ToInt32(_database.ExecuteScalar());

在这里,我每次都得到id = 0 // BUG

SQL其他存储过程:

Alter Proc2
// Some other logic
Execute @id = Proc1 @name, @value  // THIS WORKS

现在,如果我从Select SCOPE_IDENTITY()将Proc1的最后一行更改为RETURN SCOPE_IDENTITY(),则C#代码有效,但Proc2返回0.

我该怎么做才能在C#代码和Proc2中工作。

我考虑过输出参数,但我不知道如何用C#中的数据库方法调用它。

2 个答案:

答案 0 :(得分:4)

如果您想从过程中获取数据,那么正确的方法是使用输出参数。不要使用程序中的return_value。该值表示执行的状态,而不是程序中的数据。

以下是这可能是什么样子的示例。

Alter Proc Proc1 
 @name varchar(10),
 @value int,
 @IdentityValue int OUTPUT

As
Begin
    insert into Table1 values (@name,@value)
    Select @IdentityValue = SCOPE_IDENTITY()
END
select * from table1
GO

Alter Proc2
(
    @name varchar(10)
    , @value int
    , @IdentityValue int OUTPUT
)
as
    //SOme other logic
    declare @IdentityValue int
    Execute Proc1 @name, @value, @IdentityValue OUTPUT

GO

另外,请注意您在Proc1中有插入,但是您没有指定列。这是非常糟糕的做法。如果您的表结构发生变化,您的程序就会中断您应该始终在插入中指定列。

答案 1 :(得分:0)

将您的程序正文更改为如下所示,将RETURN语句更改为SELECT SCOPE_IDENTITY()

Alter Proc Proc1 
 @name varchar(10),
 @value int
As
Begin
insert into Table1 values (@name,@value);
SELECT SCOPE_IDENTITY();
END

在这种情况下,将其设为输出参数并将该输出参数设置为scope_identity

Alter Proc Proc1 
 @name varchar(10),
 @value int,
 @ID INT OUTPUT
As
Begin
insert into Table1 values (@name,@value);
SET @ID = SCOPE_IDENTITY();
END

您可以调用该程序

cmd.Parameters.Add("@ID", SqlDbType.Int, 0, "ID");
cmd.Parameters["@ID"].Direction = ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
int id = (int)cmd.Parameters["@ID"].Value;