0

大家好,我在尝试使用触发器自动更新表时遇到问题。

我正在开发一个房地产管理应用程序,我想为物业经理方面生成一个表格 ( bill),其中包含同一共享建筑物每年和每位房东收到的所有费用和付款。

我用于这部分的主要表格是:

  • building
  • charge(其中包含building_id
  • charge_payment(其中包含building_id和landlord_id as user_id

bill例如,为了生成这个chargebill(我检查了表格charge和表格charge_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

我的问题是,如果我在同一建筑物和同一年添加其他费用,我就会出错。到现在为止,我通过在每次新的充电插入之前删除表中的所有原始数据来解决这个问题billyear但这很脏:)

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