0

こんにちは、トリガーを使用してテーブルを自動更新しようとしているときに問題に直面しています。

bill私は不動産管理アプリを開発しており、不動産管理者側のために、同じ共有建物について家主ごとに年間および家主ごとに受け取ったすべての料金と支払いを含むテーブル ( ) を生成したいと考えています。

このパートで使用する主なテーブルは次のとおりです。

  • building
  • charge(含むbuilding_id)
  • charge_payment(building_idと landlord_idを含むuser_id)

このテーブル ( ) を生成するために、たとえば、テーブルに挿入する新しい料金挿入ごとにテーブルを生成するbillトリガーをテーブルに作成しました。そのためにテーブルとテーブルをチェックインします。chargebillchargecharge_payment

これがどのように見えるかです:

CREATE DEFINER=`root`@`localhost` TRIGGER `charge_AFTER_INSERT` AFTER INSERT ON `charge` FOR EACH ROW BEGIN
        
    INSERT INTO bill(building_id, user_id, year, amount, payment)
    SELECT
        p.building_id,
        ll.user_id user_id,
        bcharge_annual.year year,
        ROUND(sum(p.building_slice) * (bcharge_annual.amount), 2) amount,
        IFNULL(total_payments.payments, 0) payment
    FROM landlord ll
    LEFT JOIN property p ON ll.property_id=p.id
    LEFT JOIN (
        SELECT 
            c.building_id building_id,
            c.year,
            SUM(c.amount) amount
        FROM charge c
        WHERE c.building_id=new.building_id and c.property_id IS NULL
        GROUP BY c.year
        ) bcharge_annual ON p.building_id=bcharge_annual.building_id
    LEFT JOIN (
        SELECT 
            cp.user_id user_id, 
            cp.corresponding_year year, 
            IFNULL(sum(cp.amount), 0) payments
        FROM charge_payment cp 
        WHERE cp.corresponding_year=new.year
        GROUP BY user_id,corresponding_year
        ) total_payments ON ll.user_id=total_payments.user_id
    WHERE p.building_id=new.building_id AND (ll.ownership_end IS NULL OR ll.ownership_end > (SELECT NOW())) AND bcharge_annual.year=new.year
    GROUP BY ll.user_id,year;
    
END

私の問題は、同じ建物と同じ年に別の料金を追加すると、エラーが発生することです。bill今までは、新しい料金が挿入される前にテーブル内のすべての rawを同じように削除することで問題を解決しましたyearが、かなり汚れています :)

CREATE DEFINER=`root`@`localhost` TRIGGER `charge_AFTER_INSERT` AFTER INSERT ON `charge` FOR EACH ROW BEGIN
    DECLARE matchbillyear INT;
    
    SELECT COUNT(*) 
    INTO matchbillyear
    FROM bill b
    WHERE b.building_id=new.building_id AND b.year=new.year;
    
    IF matchbillyear > 0 THEN
        DELETE FROM bill bil
        WHERE bil.year=new.year;

    ...

だから私は考えていたので、テーブルのこの削除トリガーを削除し、テーブルchargeにトリガーを追加して、bill各行に挿入する前に、それが挿入か単なるamount更新かを確認しようとしました:

CREATE DEFINER=`root`@`localhost` TRIGGER `bill_BEFORE_INSERT` BEFORE INSERT ON `bill` FOR EACH ROW BEGIN
    DECLARE matchBillId INT;
    
    SELECT b.id 
    INTO matchBillId
    FROM bill b
    WHERE b.building_id=new.building_id AND b.year=new.year AND b.user_id=new.user_id;
    
    IF EXISTS (
        SELECT b.id 
        FROM bill b
        WHERE b.building_id=new.building_id AND b.year=new.year AND b.user_id=new.user_id) THEN
        UPDATE bill
        SET NEW.amount = amount + NEW.amount
        WHERE id = matchBillId;
    END IF;
  
END

私には良さそうに見えましたが、このエラーをスローするMySqlには間違いありません:

ERROR 1442: 1442: Can't update table 'bill' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
SQL Statement:
INSERT INTO `erem_pro`.`charge` (`building_id`, `year`, `type`, `amount`) VALUES ('1', '2021', 'Entretien', '1300.00')

誰かがそれを機能させる方法についての手がかりを持っているなら、それは素晴らしいことです。そうでなければ、アプリを再考する必要があると思います... :/

事前に感謝します。すべてを読んだらおめでとうございます:)

4

0 に答える 0