0

MySQL データベースを作成しています。id, idoftheproduct, quantitySales( ) と Supplies( )の 2 つの異なるテーブルがありid, idoftheproduct, quantityます。idoftheproduct, quantity新しい販売または新しい供給を追加するたびに、Stock( )と呼ばれる別のテーブルの値を増減させるトリガーが必要です。

4

2 に答える 2

1

要するに、しないでください。代わりにビューを作成します:

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;

SQL Fiddle の例

于 2013-06-10T15:51:51.197 に答える
0

ビューを使用したソリューションは優れたソリューションですが、常に計算を行うため、特に販売と供給のデータが大量にある場合は、時間の経過とともに遅くなる傾向があります。

したがって、トリガーを介して実装することにした場合は、少なくとも 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のデモです

于 2013-06-11T04:02:40.877 に答える