Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 触发器未正确计算总和_Mysql_Sql_Database_Triggers - Fatal编程技术网

Mysql 触发器未正确计算总和

Mysql 触发器未正确计算总和,mysql,sql,database,triggers,Mysql,Sql,Database,Triggers,我有一个触发器,它使用前一行和当前行计算总和,并在当前行的余额字段中输出总和,问题是它似乎无法计算插入到表中的第一行的总和。我的触发器是: delimiter $$ CREATE TRIGGER `ledger_calc` AFTER INSERT ON `sp_records` FOR EACH ROW BEGIN SET @PrevBal := (SELECT balance FROM ledger WHERE cmp_name = NEW.cmp_name AND inv_for = NE

我有一个触发器,它使用前一行和当前行计算总和,并在当前行的余额字段中输出总和,问题是它似乎无法计算插入到表中的第一行的总和。我的触发器是:

delimiter $$
CREATE TRIGGER `ledger_calc` AFTER INSERT ON `sp_records`
FOR EACH ROW BEGIN
SET @PrevBal := (SELECT balance FROM ledger WHERE cmp_name = NEW.cmp_name AND inv_for = NEW.inv_for ORDER BY id DESC
LIMIT 1); 
SET @CmpName := NEW.cmp_name;
SET @InvFor := NEW.inv_for;

IF (NEW.type = 'sales') THEN
SET @Type := 'sales';

INSERT INTO ledger (id,inv_for,cmp_name,date,debit,balance)
SELECT
      TransactDet.id,
     TransactDet.inv_for,
    TransactDet.cmp_name,
      TransactDet.date,
      TransactDet.tot_amnt,
      @PrevBal :=  @PrevBal + TransactDet.tot_amnt as balance
   from 
      ( select
              Transact.id,
              Transact.date,
              Transact.tot_amnt,
              Transact.cmp_name,
              Transact.inv_for

           from
              sp_records Transact
           where Transact.type = @Type
            AND Transact.inv_for = @InvFor
            AND Transact.cmp_name = @CmpName
           order by
            Transact.id DESC
            limit 1 ) as TransactDet;
ELSE
SET @Type := 'purchase';
INSERT INTO ledger (id,inv_for,cmp_name,date,credit,balance)
SELECT
      TransactDet.id,
     TransactDet.inv_for,
    TransactDet.cmp_name,
      TransactDet.date,
      TransactDet.tot_amnt,
      @PrevBal := @PrevBal - TransactDet.tot_amnt as balance
   from 
      ( select
              Transact.id,
              Transact.date,
              Transact.tot_amnt,
                Transact.cmp_name,
              Transact.inv_for
           from
              sp_records Transact
           where Transact.type = @Type
            AND Transact.inv_for = @InvFor
            AND Transact.cmp_name = @CmpName
           order by
            Transact.id DESC
            limit 1) as TransactDet;
END IF;

END;
# 此查询返回了我想要的内容。。但它似乎并没有转化为触发器

SELECT
      PreAgg.id,
      PreAgg.tot_amnt,
      @PrevBal := @PrevBal + PreAgg.tot_amnt as balance
   from 
      ( select
              YT.id,
              YT.tot_amnt
           from
              sp_records YT
           order by
              YT.id ) as PreAgg,
      ( select @PrevBal := 0.00 ) as SqlVars

请尝试一下这个:

delimiter $$

CREATE TRIGGER `ledger_calc` BEFORE INSERT ON `sp_records`
FOR EACH ROW
BEGIN
    SET @PrevBal : = (
            SELECT balance
            FROM ledger
            WHERE cmp_name = NEW.cmp_name
                AND inv_for = NEW.inv_for
            ORDER BY id DESC LIMIT 1
            );

    INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance)
    SELECT Transact.id, Transact.inv_for, Transact.cmp_name, Transact.DATE, Transact.tot_amnt, @PrevBal + Transact.tot_amnt AS balance
    FROM sp_records Transact
    WHERE Transact.type = NEW.type
        AND Transact.inv_for = NEW.inv_for
        AND Transact.cmp_name = NEW.cmp_name
    ORDER BY Transact.id DESC limit 1;
END $$
我不知道,您的表结构是什么样子的,但您最好忘记触发器,直接执行

INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance)
SELECT t.id, t.inv_for, t.cmp_name, t.DATE, t.tot_amnt, l.balance + t.tot_amnt AS balance
FROM sp_records t
INNER JOIN ledger l ON t.inv_for = l.inv_for AND t.cmp_name = l.cmp_name
WHERE t.type = 'a_value'
    AND t.inv_for = 'another_value'
    AND t.cmp_name = 'yet_another_value'
ORDER BY t.id DESC limit 1;
或者作为一个触发器

DELIMITER $$
CREATE TRIGGER `ledger_calc` AFTER INSERT ON `sp_records`
FOR EACH ROW
BEGIN
    INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance)
    SELECT t.id, t.inv_for, t.cmp_name, t.DATE, t.tot_amnt, l.balance + t.tot_amnt AS balance
    FROM sp_records t
    INNER JOIN ledger l ON t.inv_for = l.inv_for AND t.cmp_name = l.cmp_name
    WHERE t.type = NEW.type
        AND t.inv_for = NEW.inv_for
        AND t.cmp_name = NEW.cmp_name
    ORDER BY t.id DESC limit 1;
END $$

如果所有这些都没有帮助,那么样本数据和期望的结果会很有帮助,最好是在

@MoniXx上,当您想将其写入触发器时,会出现什么问题?另外,您应该发布您尝试的整个触发器,否则就不清楚触发器应该做什么。问题是,如果我使用您的触发器,“prevBal”变量将在第一次调用触发器时变为null或没有行,就像插入之前一样。。我们希望它在insert之前,因此第一行的余额返回为0。