如何在SQL中按顺序逐行更新两个表

如何在SQL中按顺序逐行更新两个表,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,我需要根据彼此的数据并行更新两个表 下面是两个表的表结构 产品表: 订单表: 我需要更新订单表中的状态,以确认/拒绝以下情况: ProductOrderQuantity应小于Product表中的ProductQuantity 报价价格应介于最低价格和最高价格之间 如果两个条件都匹配,则更新订单表中的状态以确认/拒绝,并将OrderProcessDate作为其处理的日期 此更新应按顺序对订单表中的每一行执行,一旦从行状态更新为确认状态,立即将ProductQuantity更新为ProductQua

我需要根据彼此的数据并行更新两个表

下面是两个表的表结构

产品表:

订单表:

我需要更新订单表中的状态,以确认/拒绝以下情况:

ProductOrderQuantity应小于Product表中的ProductQuantity

报价价格应介于最低价格和最高价格之间

如果两个条件都匹配,则更新订单表中的状态以确认/拒绝,并将OrderProcessDate作为其处理的日期


此更新应按顺序对订单表中的每一行执行,一旦从行状态更新为确认状态,立即将ProductQuantity更新为ProductQuantity-ProductOrderQuantity,您可以使用

select 'OK'
FROM Order
INNER JOIN Product ON Product.ProductId = Order.ProductId
WHERE order.ProductOrderQuantity < Product.ProductQuantity
  AND order.OfferPrice between Product.min_price and Product.Max_price
最后,您可以尝试在JOIN中使用更新来检查条件

update Order 
SET status = "Confirm/Reject",
    OrderProcessDate =  GETDATE()
FROM Order
INNER JOIN Product ON Product.ProductId = Order.ProductId
WHERE order.ProductOrderQuantity < Product.ProductQuantity
  AND order.OfferPrice between Product.min_price and Product.Max_price

我假设订单是按OrderId排序的。这意味着,顺序越低,优先级越高

看到下面的代码,我想它会对你有所帮助

CREATE TABLE #OrderJobDispatch(
  OrderId BIGINT
)

DECLARE @orderID BIGINT;

INSERT INTO #OrderJobDispatch (OrderId)
SELECT OrderId
FROM
  [Order]
WHERE
  Status = 'Placed'

WHILE EXISTS(SELECT * FROM #OrderJobDispatch)
BEGIN
  -- take the highest priority order
  SET @orderId = SELECT TOP(1) OrderId FROM #OrderJobDispatch ORDER BY OrderId

  -- update Order table if the condition matches
  UPDATE o
  SET o.Status = 'Confirm/Reject'
  FROM
    [Order] AS o
  INNER JOIN
    [Product] AS p
  ON
    o.ProductId = p.ProductId
  WHERE
    o.OrderId = @orderId
  AND
    o.ProductOrderQuantity < p.ProductQuantity
  AND 
    o.OfferPrice BETWEEN p.MinPrice AND p.MaxPrice

  -- update Product table if it is appropriate
  UPDATE p
  SET ProductQuantity = p.ProductQuantity - o.ProductOrderQuantity 
  FROM 
    [Product] AS p
  INNER JOIN
    [Order] AS o
  ON
    p.ProductId = o.ProductId
  WHERE
    o.OrderId = @orderId
  AND
    o.Status = 'Confirm/Reject'

  DELETE FROM #OrderJobDispatch
  WHERE OrderId = @orderId
END

在这里,我们实际上像队列一样使用OrderJobDispatch表。虽然在类似队列的表中只有一行,但我们使用OrderId进行操作。

我无法测试代码,但步骤应该很清楚:

while 1 = 1
begin
  declare @OrderId int

  begin transaction

  select @OrderId = min(OrderId)
  from Order
  where Status = "Placed"

  if @@rowcount = 0
  begin
    /* Done with processing all orders */
    commit transaction
    break
  end

  update Order
  set Status = "Confirm"
  from Order o
  inner join Product p
  on p.ProductId = o.ProductId
  where o.OrderId = @OrderId
  and o.ProductOrderQuantity < p.ProductQuantity
  and o.OfferPrice between p.MinPrice and p.MaxPrice

  if @@rowcount = 1
  begin
    update Product
    set ProductQuantity = p.ProductQuantity - o.ProductOrderQuantity
    from Product p
    inner join Order o
    on p.ProductId = o.ProductId
    where o.OrderId = @OrderId

    commit transaction
  end
  else
  begin
    update Order
    set Status = "Reject"
    from Order o
    inner join Product p
    on p.ProductId = o.ProductId
    where o.OrderId = @OrderId

    commit transaction
  end
end

忘记顺序/并行概念吧。如果不同的记录需要同时保持一致,您需要使用一个事务。是的,但我需要订单表的第一行应该更新,然后是产品表。执行之后,应该是订单表的第二行,然后是产品表,它一直运行到订单表的最后一行。我建议搜索使用表作为队列。您需要有一个指定“订单”的列。在这个阶段看起来像OrderId,对吗?谢谢scaisEdge。在上面的查询中,产品表将如何更新?条件定义在我问题的最后一行。如果设置订单id并添加where条件,则更新后的条件应包含订单的所有具有有效条件的行。。
CREATE TABLE #OrderJobDispatch(
  OrderId BIGINT
)

DECLARE @orderID BIGINT;

INSERT INTO #OrderJobDispatch (OrderId)
SELECT OrderId
FROM
  [Order]
WHERE
  Status = 'Placed'

WHILE EXISTS(SELECT * FROM #OrderJobDispatch)
BEGIN
  -- take the highest priority order
  SET @orderId = SELECT TOP(1) OrderId FROM #OrderJobDispatch ORDER BY OrderId

  -- update Order table if the condition matches
  UPDATE o
  SET o.Status = 'Confirm/Reject'
  FROM
    [Order] AS o
  INNER JOIN
    [Product] AS p
  ON
    o.ProductId = p.ProductId
  WHERE
    o.OrderId = @orderId
  AND
    o.ProductOrderQuantity < p.ProductQuantity
  AND 
    o.OfferPrice BETWEEN p.MinPrice AND p.MaxPrice

  -- update Product table if it is appropriate
  UPDATE p
  SET ProductQuantity = p.ProductQuantity - o.ProductOrderQuantity 
  FROM 
    [Product] AS p
  INNER JOIN
    [Order] AS o
  ON
    p.ProductId = o.ProductId
  WHERE
    o.OrderId = @orderId
  AND
    o.Status = 'Confirm/Reject'

  DELETE FROM #OrderJobDispatch
  WHERE OrderId = @orderId
END
while 1 = 1
begin
  declare @OrderId int

  begin transaction

  select @OrderId = min(OrderId)
  from Order
  where Status = "Placed"

  if @@rowcount = 0
  begin
    /* Done with processing all orders */
    commit transaction
    break
  end

  update Order
  set Status = "Confirm"
  from Order o
  inner join Product p
  on p.ProductId = o.ProductId
  where o.OrderId = @OrderId
  and o.ProductOrderQuantity < p.ProductQuantity
  and o.OfferPrice between p.MinPrice and p.MaxPrice

  if @@rowcount = 1
  begin
    update Product
    set ProductQuantity = p.ProductQuantity - o.ProductOrderQuantity
    from Product p
    inner join Order o
    on p.ProductId = o.ProductId
    where o.OrderId = @OrderId

    commit transaction
  end
  else
  begin
    update Order
    set Status = "Reject"
    from Order o
    inner join Product p
    on p.ProductId = o.ProductId
    where o.OrderId = @OrderId

    commit transaction
  end
end