MySQL データベースを作成しています。id, idoftheproduct, quantity
Sales( ) と Supplies( )の 2 つの異なるテーブルがありid, idoftheproduct, quantity
ます。idoftheproduct, quantity
新しい販売または新しい供給を追加するたびに、Stock( )と呼ばれる別のテーブルの値を増減させるトリガーが必要です。
2 に答える
要するに、しないでください。代わりにビューを作成します:
CREATE VIEW Stock
AS
SELECT IDofTheProduct, SUM(Quantity) AS Quantity
FROM ( SELECT IDofTheProduct, Quantity
FROM Supplies
UNION ALL
SELECT IdOfTheProduct, -Quantity
FROM Sales
) t
GROUP BY IDofTheProduct;
このようにして、基になるテーブルが変更されると、ビューが変更されます。これにより、更新/挿入中のオーバーヘッドが少なくなり、何らかの理由でトリガーが起動されなかった場合でも、常に正確になります。
編集
申し訳ありませんが、MySQL ではビューでのサブクエリが許可されていないことを忘れていました。1 つの解決策は、サブクエリの代わりに使用する新しいビューを作成することです。
CREATE VIEW SalesAndSupplies
AS
SELECT 'Supplies' AS `Type`,
IDofTheProduct,
Quantity
FROM Supplies
UNION ALL
SELECT 'Sales' AS `Type`,
IDofTheProduct,
-Quantity
FROM Sales;
CREATE VIEW Stock
AS
SELECT IDofTheProduct, SUM(Quantity) AS Quantity
FROM SalesAndSupplies
GROUP BY IDofTheProduct;
ビューを使用したソリューションは優れたソリューションですが、常に計算を行うため、特に販売と供給のデータが大量にある場合は、時間の経過とともに遅くなる傾向があります。
したがって、トリガーを介して実装することにした場合は、少なくとも 4 つのトリガー (両方のテーブルでの挿入と削除) が必要です。それらはすべてストックを更新するため、コードのその部分はストアドプロシージャに分解する方がよいでしょう。
在庫を更新するストアド プロシージャ
CREATE PROCEDURE sp_update_stock(IN pid INT, IN qty DECIMAL(11, 3))
INSERT INTO stock (idoftheproduct, quantity)
VALUES (pid, qty)
ON DUPLICATE KEY UPDATE quantity = quantity + qty;
を含む行idoftheproduct
が実行時に存在しない場合は、作成されます。それ以外の場合は、変更を反映するために更新されます。
今トリガー
CREATE TRIGGER tg_sales_insert
AFTER INSERT ON sales
FOR EACH ROW
CALL sp_update_stock(NEW.idoftheproduct, -1 * NEW.quantity);
CREATE TRIGGER tg_supplies_insert
AFTER INSERT ON supplies
FOR EACH ROW
CALL sp_update_stock(NEW.idoftheproduct, NEW.quantity);
CREATE TRIGGER tg_sales_delete
AFTER DELETE ON sales
FOR EACH ROW
CALL sp_update_stock(OLD.idoftheproduct, OLD.quantity);
CREATE TRIGGER tg_supplies_delete
AFTER DELETE ON supplies
FOR EACH ROW
CALL sp_update_stock(OLD.idoftheproduct, -1 * OLD.quantity);
これで、Sales と Supplies への挿入と削除ができるようになりました。
INSERT INTO Supplies VALUES (NULL, 1, 100), (NULL, 1, 50), (NULL, 1, 75);
INSERT INTO Sales VALUES (NULL, 1, 2),(NULL, 1, 10), (NULL, 1, 5);
DELETE FROM Sales WHERE id = 1;
DELETE FROM Supplies WHERE id = 3;
見てみるstock
とわかります
| | IDOFTHEPRODUCT | 数量 | ------------------------------ | | 1 | 135 |
これがSQLFiddleのデモです