从Sql中选择范围标识
本文关键字:范围 标识 选择 Sql | 更新日期: 2023-09-27 18:02:52
我正在执行一个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
现在,如果我将Proc1的最后一行从RETURN SCOPE_IDENTITY()
更改为Select SCOPE_IDENTITY()
,则c#代码可以工作,但Proc2返回0。
我该怎么做才能使它在c#代码和Proc2中也能工作呢?
我考虑了一个输出参数,但我不知道如何在c#中调用我的这个数据库方法。
如果您希望从过程中获取数据,正确的做法是使用输出参数。不要使用过程中的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中有一个插入,但您没有指定列。这是非常糟糕的做法。如果你的表结构改变了,你的过程就坏了。
将您的过程体更改为如下所示,将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;