J'ai 3 tableaux (simplifiés):
tblOrder(OrderId INT)
tblVariety(VarietyId INT,Stock INT)
tblOrderItem(OrderId,VarietyId,Quantity INT)
Si je passe une commande, je baisse le niveau de stock en utilisant ceci:
UPDATE tblVariety
SET tblVariety.Stock = tblVariety.Stock - tblOrderItem.Quantity
FROM tblVariety
INNER JOIN tblOrderItem ON tblVariety.VarietyId = tblOrderItem.VarietyId
INNER JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId
WHERE tblOrder.OrderId = 1
Très bien, jusqu'à ce qu'il y ait deux lignes dans tblOrderItem avec le même VarietyId pour le même OrderId. Dans ce cas, une seule des lignes est utilisée pour la mise à jour du stock. Il semble être en train de faire un GROUP BY VarietyId.
Quelqu'un peut-il nous éclairer? Merci beaucoup.
Je suppose que parce que vous nous avez montré un schéma simplifié, certaines informations manquent qui détermineraient pourquoi les valeurs VarietyID répétées pour un OrderID donné.
Lorsque vous avez plusieurs lignes, SQL Server sélectionne arbitrairement l'une d'entre elles pour la mise à jour.
Si tel est le cas, vous devez d'abord grouper
UPDATE V
SET
Stock = Stock - foo.SumQuantity
FROM
tblVariety V
JOIN
(SELECT SUM(Quantity) AS SumQuantity, VarietyID
FROM tblOrderItem
JOIN tblOrder ON tblOrderItem.OrderId = tblOrder.OrderId
WHERE tblOrder.OrderId = 1
GROUP BY VarietyID
) foo ON V.VarietyId = foo.VarietyId
Si ce n'est pas le cas, la table OrderItems PK est erronée car si elle autorise les combinaisons OrderID/VarietyID en double (la PK doit être OrderID/VarietyID, ou celles-ci doivent être contraintes comme uniques)
À partir de la documentation UPDATE
Les résultats d'une instruction UPDATE ne sont pas définis si l'instruction inclut une clause FROM qui n'est pas spécifiée de telle sorte qu'une seule valeur est disponible pour chaque occurrence de colonne mise à jour (en d'autres termes, si l'instruction UPDATE n'est pas déterministe). Par exemple, étant donné l'instruction UPDATE dans le script suivant, les deux lignes de la table s répondent aux qualifications de la clause FROM dans l'instruction UPDATE, mais c'est indéfini quelle ligne de s est utilisée pour mettre à jour la ligne du tableau t.
CREATE TABLE s (ColA INT, ColB DECIMAL(10,3))
GO
CREATE TABLE t (ColA INT PRIMARY KEY, ColB DECIMAL(10,3))
GO
INSERT INTO s VALUES(1, 10.0)
INSERT INTO s VALUES(1, 20.0)
INSERT INTO t VALUES(1, 0.0)
GO
UPDATE t
SET t.ColB = t.ColB + s.ColB
FROM t INNER JOIN s ON (t.ColA = s.ColA)
GO
Vous faites une mise à jour. Il sera mis à jour une fois.
Modifier: pour résoudre, vous pouvez ajouter une sous-requête qui regroupera vos articles de commande par ordre et variété, avec une somme sur le montant.