如何在插入中使用SCOPE_IDENTITY()

时间:2014-12-19 21:54:48

标签: c# sql entity-framework sql-server-2008

我希望在插入之前获得新的id(Identity)。所以,使用这段代码:

select SCOPE_IDENTITY()  AS NewId from tblName

但是得到了这个:

1- Null

2 Null

4 个答案:

答案 0 :(得分:3)

评论过于冗长。

考虑这个概念究竟有多么缺陷。 identity属性是尝试插入次数的运行记录。您希望向用户返回尚不存在的行的标识。考虑如果插入中的值导致它失败,会发生什么。您已经告诉用户身份将是什么,但插入失败,以便已经消耗了身份。您应该向用户报告行实际存在时的值,即插入后的值。

答案 1 :(得分:3)

计算栏目版本

您必须在sql server上执行此操作才能添加列。

alter table TableName add Code as (name + cast(id as varchar(200)))

现在你的结果集将始终将Code作为名称+ id值,这很好,因为即使字段被更改(例如名称),该列仍将使用该表达式进行更新。


实体框架选项(不太理想)

您提到您正在使用Entity Framework。您需要在插入期间连接同一记录中的字段上的ID。 SQL(在触发器之外)或实体框架中没有能力一步完成您想要的操作。

你需要做这样的事情:

var obj = new Thing{ field1= "some value", field2 = ""};
context.ThingTable.Add(obj);
context.SaveChanges();
obj.field2 = "bb" + obj.id; //after the first SaveChanges is when your id field would be populated
context.SaveChanges();

原文回答: 如果你真的必须向用户显示这个值,那么安全的方法就是这样:

begin tran
insert into test(test) values('this is something')
declare @pk int = scope_identity()
print @pk

您现在可以返回@pk中的值,并让用户确定其是否可接受。如果是,则发出COMMIT else发出ROLLBACK命令。

然而,这不是一个非常好的设计,我认为滥用身份值的方式会被误用。此外,您应该知道如果执行回滚,将使用的ID将丢失,并且不会被删除。再次使用。

答案 2 :(得分:1)

我无法理解你为什么要在插入之前向用户显示该身份,我相信(如@SeanLange所说)这不是自定义且无用的,但如果你坚持我认为你可以做一些体弱的方式。其中之一是

  • 1)插入新行,然后使用SCOPE_IDENTITY()获取ID并显示给用户
  • 2)然后如果要取消操作删除行并重置
    身份(如有必要)使用DBCC CHECKIDENT('[Table Name]', RESEED, [Identity Seed])方法

其他方式是不使用Identity列并自行管理id列,必须清楚这种方法不能在并发场景中工作。

答案 3 :(得分:0)

我想也许你会将SQL身份与ORACLE序列混淆。 他们的工作完全不同。 使用ORACLE序列,您将在插入记录之前获得序列。 使用SQL标识,通过SCOPE_IDENTITY()函数在插入后生成的最后一个标识。

如果您确实需要在插入之前向用户显示ID,最好的办法是将计数器保存在单独的表中,然后读取当前值,并将其递增1。只要数字中的“空白”不成问题。