SQL Server 在另一列的上下文中唯一的自动增量列
假设该表有两列:
ParentEntityId int foreign key
Number int
ParentEntityId
是另一个表的外键。
Number
是一个本地身份,即它在单个ParentEntityId
中是唯一的。
通过这两列上的唯一键可以轻松实现唯一性。
如何使 Number
在插入时在 ParentEntityId
的上下文中自动递增?
附录 1
澄清问题,这是一个摘要。
ParentEntity
具有多个 ChildEntity
,并且每个 ChiildEntity
在其 上下文中应该有一个唯一的增量
。Number
父实体
附录 2
将 ParentEntity
视为客户。
将 ChildEntity
视为 Order。
因此,每个客户的订单应编号为 1、2、3 等。
Suppose the table with two columns:
ParentEntityId int foreign key
Number int
ParentEntityId
is a foreign key to another table.
Number
is a local identity, i.e. it is unique within single ParentEntityId
.
Uniqueness is easily achieved via unique key over these two columns.
How to make Number
be automatically incremented in the context of the ParentEntityId
on insert?
Addendum 1
To clarify the problem, here is an abstract.
ParentEntity
has multiple ChildEntity
, and each ChiildEntity
should have an unique incremental Number
in the context of its ParentEntity
.
Addendum 2
Treat ParentEntity
as a Customer.
Treat ChildEntity
as an Order.
So, orders for every customer should be numbered 1, 2, 3 and so on.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,这种类型的列没有本机支持,但您可以使用触发器来实现它:
未经测试,但我很确定它会起作用。如果您有主键,您也可以将其实现为
AFTER
触发器(我不喜欢使用INSTEAD OF
触发器,当您需要修改它们时它们更难理解6个月后)。只是为了解释这里发生的事情:
SERIALIZABLE
是最严格的隔离模式;它保证一次只有一个数据库事务可以执行这些语句,这是我们为了保证这一“序列”的完整性所需要的。请注意,这会不可逆地提升整个事务,因此您不会希望在长时间运行的事务中使用它。CTE 选取每个父 ID 已使用的最高编号;
ROW_NUMBER
为每个父ID(PARTITION BY
)生成一个从数字1开始的唯一序列;如果有一个可以获取新序列,我们会将其添加到前一个最大值。我可能还应该提到,如果您一次只需要插入一个新的子实体,那么您最好通过存储过程而不是使用触发器来集中这些操作 - 您肯定会从中获得更好的性能。这就是目前在 SQL '08 中使用
hierarchyid
列完成的方式。Well, there's no native support for this type of column, but you could implement it using a trigger:
Not tested but I'm pretty sure it'll work. If you have a primary key, you could also implement this as an
AFTER
trigger (I dislike usingINSTEAD OF
triggers, they're harder to understand when you need to modify them 6 months later).Just to explain what's going on here:
SERIALIZABLE
is the strictest isolation mode; it guarantees that only one database transaction at a time can execute these statements, which we need in order to guarantee the integrity of this "sequence." Note that this irreversibly promotes the entire transaction, so you won't want to use this inside of a long-running transaction.The CTE picks up the highest number already used for each parent ID;
ROW_NUMBER
generates a unique sequence for each parent ID (PARTITION BY
) starting from the number 1; we add this to the previous maximum if there is one to get the new sequence.I probably should also mention that if you only ever need to insert one new child entity at a time, you're better off just funneling those operations through a stored procedure instead of using a trigger - you'll definitely get better performance out of it. This is how it's currently done with
hierarchyid
columns in SQL '08.需要添加 OUTPUT 子句来触发 Linq to SQL 兼容性。
例如:
Need add
OUTPUT
clause to trigger for Linq to SQL сompatibility.For example:
据我了解,这解决了问题::-)
This solves the question as I understand it: :-)