简体   繁体   English

如何不在插入中使用SCOPE_IDENTITY()

[英]how to use SCOPE_IDENTITY() not in insert

I want to get new id(Identity) before insert it. 我想在插入它之前获取新的id(Identity)。 so, use this code: 因此,使用以下代码:

select SCOPE_IDENTITY()  AS NewId from tblName

but is get this: 但是得到这个:

1- Null 1-空

2- Null 2-空

This is too verbose for a comment. 这太冗长,无法发表评论。

Consider how flawed this concept really is. 考虑一下这个概念的真正缺陷。 The identity property is a running tally of the number of attempted inserts. identity属性是尝试插入次数的连续计数。 You are wanting to return to the user the identity of a row that does not yet exist. 您想向用户返回尚不存在的行的标识。 Consider what would happen if you have values in the insert that cause it too fail. 考虑如果插入中的值导致它也失败,将会发生什么情况。 You already told the user what the identity would be but the insert failed so that identity has already been consumed. 您已经告诉用户身份是什么,但是插入失败,因此身份已被使用。 You should report to the user the value when the row actually exists, which is after the insert. 当行实际存在时(插入之后),您应该向用户报告该值。

COMPUTED COLUMN VERSION 计算列版本

You'll have to do this on the sql server to add the column. 您必须在sql服务器上执行此操作才能添加列。

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

Now your result set will always have Code as the name + id value, nice because this column will remain updated with that expression even if the field are changed (such as name). 现在,您的结果集将始终使用Code作为名称+ id值,这很不错,因为即使更改了字段(例如name),该列仍将使用该表达式进行更新。


Entity Framework Option (Less ideal) 实体框架选项(不太理想)

You mentioned you are using Entity Framework. 您提到您正在使用实体框架。 You need to concatenate the ID on a field within the same record during insert. 在插入期间,您需要在同一记录内的字段上串联ID。 There is no capacity in SQL (outside of Triggers) or Entity Framework to do what you are wanting in one step. SQL(触发器之外)或实体框架没有能力一步完成您想要的事情。

You need to do something like this: 您需要执行以下操作:

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();

ORIGINAL Answer: If you really must show this value to the user then the safe way to do it would be something like this: 原始答案:如果您确实必须向用户显示此值,那么执行此操作的安全方法将如下所示:

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

You can now return the value in @pk and let the user determine if its acceptable. 现在,您可以在@pk返回该值,并让用户确定其是否可接受。 If it is then issue a COMMIT else issue the ROLLBACK command. 如果发出,则发出COMMIT否则发出ROLLBACK命令。

This however is not a very good design and I would think a misuse of the how identity values are generated. 但是,这不是一个很好的设计,我会误认为如何生成标识值。 Also you should know if you perform a rollback, the ID that would of been used is lost and wont' be used again. 您还应该知道,如果执行回滚,将丢失将要使用的ID,并且不会再次使用它。

I can't understand why you want to show that identity to user before insert, I believe (as @SeanLange said) that is not custom and not useful, but if you insist I think you can do some infirm ways. 我不明白为什么您要在插入之前向用户显示该身份,我相信(如@SeanLange所说)这不是自定义的,也没有用,但是如果您坚持认为我可以采取一些无效的方法。 One of them is 其中之一是

  • 1) Insert new row then get ID with SCOPE_IDENTITY() and show to user 1)插入新行,然后使用SCOPE_IDENTITY()获取ID并显示给用户
  • 2) Then if you want to cancel operation delete the row and reset 2)然后,如果要取消操作,请删除该行并重置
    identity (if necessary) with DBCC CHECKIDENT('[Table Name]', RESEED, [Identity Seed]) method DBCC CHECKIDENT('[Table Name]', RESEED, [Identity Seed])方法获得身份(如有必要)

Other way is not using the Identity column and manage id column by yourself and it must be clear this approach can't be work in concurrency scenarios. 另一种方法是不自己使用“标识”列和“管理ID”列,必须明确的是,这种方法在并发方案中不起作用。

I think perhaps you're confusing the SQL identity with a ORACLE sequence. 我认为也许您是在将SQL身份与ORACLE序列混淆。 They work completely different. 他们的工作完全不同。 With the ORACLE sequence you'll get the sequence before you insert the record. 使用ORACLE序列,您将在插入记录之前获得序列。 With a SQL Identity, the last identity generated AFTER the insert in available via the SCOPE_IDENTITY() function. 使用SQL身份,可以通过SCOPE_IDENTITY()函数在插入后生成最后一个身份。

If you really need to show the ID to the user before the insert, your best bet is to keep a counter in a separate table, and read the current value, and increment that by one. 如果您确实需要在插入之前向用户显示ID,则最好的选择是将计数器保留在单独的表中,并读取当前值,然后将该值加1。 As long as "gaps" in the numbers aren't a problem. 只要数字中的“空白”不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM