帮助sql语句

时间:2010-10-11 02:00:48

标签: sql sql-server visual-studio-2008

我想保证将令牌分配给订单。所有可用令牌都在Token表中,每个令牌只能分配给1个订单。这是我提出的SQL:

SET XACT_ABORT ON;
BEGIN TRANSACTION

-- Reserve token.
SELECT @token = token, @tokenId = id FROM Tokens WITH (UPDLOCK) WHERE taken = 0;
-- Take token.
UPDATE Tokens SET taken = 1 WHERE id = @tokenId;
-- Assign token to the order.
UPDATE Orders SET token = @token WHERE ID = @orderId;

COMMIT TRANSACTION

以上代码可以保证

  1. 如果Tokens表中有可用的令牌,那么它将被选中并分配给订单。
  2. 每个令牌不会被分配到超过1个订单。
  3. 声明永远不会失败。
  4. 您是否看到此声明存在任何其他潜在问题?

1 个答案:

答案 0 :(得分:2)

为什么不在令牌表中放置一个可以为空的OrderId,而不是enter code here“take”属性。这只用一个列属性来实现目标。

Update Tokens SET 
  Orderid = @orderId  
Where tokenId = (Select Min(TokenId)
                 From Tokens
                 Where Orderid is Null)

编辑:添加架构以说明一对一或零关系

Tokens
TokenId integer non-null PK
... other attributes
enter code here


Orders
OrderId Integer Non-Null PK, FK to Tokens.TokenId
... other attributes

现在,您需要做的就是在创建新订单记录时使用令牌表中的可用tokenId。

Insert Orders (OrderId, [Other attributes])
Select Min(TokenId), [Other values]
From Tokens t
Where Not Exists
  (Select * From Orders
   Where OrderId = t.TokenId)