列c1 int和c2 int的复合键,其中c2是IDENTITY,每个c1都有一系列独立的值

时间:2013-08-19 07:27:12

标签: sql-server sql-server-2008 tsql

假设我们有一个带有表订单的网上商店。

它有复合键

OrderID int, ShopID int

如果我

insert into Orders (ShopID) values (3)

我希望订单包含:

OrderID ShopID
      1      3

然后

insert into Orders (ShopID) values (4)

它应该包含

OrderID ShopID
      1      3
      1      4

如果我

插入订单(ShopID)值(3)

它应该包含

OrderID ShopID
      1      3
      1      4
      2      3

没有手动尝试插入记录的黑客攻击,增加了例如

中描述的OrderID

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/792a5b82-2d13-46bd-8650-a75a74ea222f/composite-primary-key-with-auto-increment-column

我之所以认为这个解决方案是一个黑客,因为当我只有一个列时我没有手动插入记录而且没有逻辑上的原因我需要求助于我指定的那种解决方案要求。

我正在使用T-SQL,我听说过一些关于irc的谣言,其中有一些版本支持这个,但我不知道以哪种方式。

当然,问题还延伸到其他RDBM:s。

1 个答案:

答案 0 :(得分:3)

您要求SQL Server无法提供的功能。现在,如果OrderID是IDENTITY,那么您将获得一个自动增量字段,因此每个插入都将生成一个新的订单ID。如果这不是您想要的,并且您实际上只希望OrderID基于其他规则增加,那么您运气不好 - 您将需要使用业务逻辑并手动管理递增。

应该避免后者:手动跟踪和决定何时更新容易发生竞赛或序列化访问(基本上如果两个线程同时执行SET @NewOrderID = (SELECT MAX(OrderID) + 1),它们将得到相同的结果)。 IDENTITY可能是更好的答案 - 不清楚为什么你希望每个商店拥有自己的OrderIDs。

就“我听过一些谣言......”而言,我确实想知道这是否是带有PARTITION BY子句的ROW_NUMBER()。这对您没有帮助:虽然您可以使用SELECT语句根据给定列重新启动计数器,但这是动态的,并且无法保证在查询1上生成的行号对于下一个查询将是相同的,取决于如何插入行以及如何查询(如果您严格控制行的插入方式,那么您可以保证 - 但这是业务规则以及SQL Server无法实施的内容)。