我希望在插入之前获得新的id(Identity)。所以,使用这段代码:
select SCOPE_IDENTITY() AS NewId from tblName
但是得到了这个:
1- Null
2 Null
答案 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所说)这不是自定义且无用的,但如果你坚持我认为你可以做一些体弱的方式。其中之一是
DBCC CHECKIDENT('[Table Name]', RESEED,
[Identity Seed])
方法其他方式是不使用Identity列并自行管理id列,必须清楚这种方法不能在并发场景中工作。
答案 3 :(得分:0)
我想也许你会将SQL身份与ORACLE序列混淆。 他们的工作完全不同。 使用ORACLE序列,您将在插入记录之前获得序列。 使用SQL标识,通过SCOPE_IDENTITY()函数在插入后生成的最后一个标识。
如果您确实需要在插入之前向用户显示ID,最好的办法是将计数器保存在单独的表中,然后读取当前值,并将其递增1。只要数字中的“空白”不成问题。