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