UPDATE:
固定查詢:
set @paid = 200;
update invoice i
set
i.paid_amount = if(@paid <= total_amount, @paid, total_amount),
i.status = case when paid_amount = 0 then 'unpaid' when total_amount = paid_amount then 'paid' when paid_amount > 0 and paid_amount < total_amount then 'partial' else 'wtf' end,
i.id = if(@paid := if(@paid <= total_amount, 0, @paid - total_amount), i.id, i.id)
where i.customer_id = 16
order by id /*or whatever columns determines the order of the invoices*/
;
與以下嘗試過了,現在它工作:
mysql> drop table if exists invoice;
Query OK, 0 rows affected (0.00 sec)
mysql> create table invoice (
-> id int auto_increment primary key,
-> customer_id int,
-> total_amount decimal(10,2),
-> paid_amount decimal(10,2) default 0,
-> status varchar(50) default 'unpaid'
->);
Query OK, 0 rows affected (0.06 sec)
mysql>
mysql> insert into invoice (customer_id, total_amount) values
-> (3, 0),
-> (8, 303.75),
-> (8, 200.00),
-> (16, 303.75),
-> (16, 200.00);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql>
mysql> select * from invoice;
+----+-------------+--------------+-------------+--------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+--------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 0.00 | unpaid |
| 3 | 8 | 200.00 | 0.00 | unpaid |
| 4 | 16 | 303.75 | 0.00 | unpaid |
| 5 | 16 | 200.00 | 0.00 | unpaid |
+----+-------------+--------------+-------------+--------+
5 rows in set (0.01 sec)
mysql>
mysql>
mysql> set @paid = 400;
Query OK, 0 rows affected (0.00 sec)
mysql> update invoice i
-> set
-> i.paid_amount = if(@paid <= total_amount, @paid, total_amount),
-> i.status = case when paid_amount = 0 then 'unpaid' when total_amount = paid_amount then 'paid' when paid_amount > 0 and paid_amount < total_amount then 'partial' else 'wtf' end,
-> i.id = if(@paid := if(@paid <= total_amount, 0, @paid - total_amount), i.id, i.id)
-> where i.customer_id = 8
-> order by id /*or whatever columns determines the order of the invoices*/
-> ;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql>
mysql> select * from invoice;
+----+-------------+--------------+-------------+---------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+---------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 303.75 | paid |
| 3 | 8 | 200.00 | 96.25 | partial |
| 4 | 16 | 303.75 | 0.00 | unpaid |
| 5 | 16 | 200.00 | 0.00 | unpaid |
+----+-------------+--------------+-------------+---------+
5 rows in set (0.00 sec)
mysql>
mysql> set @paid = 200;
Query OK, 0 rows affected (0.00 sec)
mysql> update invoice i
-> set
-> i.paid_amount = if(@paid <= total_amount, @paid, total_amount),
-> i.status = case when paid_amount = 0 then 'unpaid' when total_amount = paid_amount then 'paid' when paid_amount > 0 and paid_amount < total_amount then 'partial' else 'wtf' end,
-> i.id = if(@paid := if(@paid <= total_amount, 0, @paid - total_amount), i.id, i.id)
-> where i.customer_id = 16
-> order by id /*or whatever columns determines the order of the invoices*/
-> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 2 Changed: 1 Warnings: 0
mysql>
mysql> select * from invoice;
+----+-------------+--------------+-------------+---------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+---------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 303.75 | paid |
| 3 | 8 | 200.00 | 96.25 | partial |
| 4 | 16 | 303.75 | 200.00 | partial |
| 5 | 16 | 200.00 | 0.00 | unpaid |
+----+-------------+--------------+-------------+---------+
5 rows in set (0.00 sec)
原來的答覆:
你根本不需要觸發器,更不用說光標了(我總是儘量避免使用這些觸發器)。您知道您剛剛插入付款表的customer_id。然後在插入後觸發此更新語句。
/*table serving as example*/
drop table if exists invoice;
create table invoice (
id int auto_increment primary key,
customer_id int,
total_amount decimal(10,2),
paid_amount decimal(10,2) default 0,
status varchar(50) default 'unpaid'
);
/*sample data*/
insert into invoice (customer_id, total_amount) values
(3, 0),
(8, 303.75),
(8, 200.00);
select * from invoice;
+----+-------------+--------------+-------------+--------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+--------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 0.00 | unpaid |
| 3 | 8 | 200.00 | 0.00 | unpaid |
+----+-------------+--------------+-------------+--------+
set @paid = 400;
update invoice i
set
i.paid_amount = if(@paid - total_amount >= 0, total_amount, total_amount - @paid),
i.status = if(@paid - total_amount >= 0, 'paid', 'partial'),
i.id = if(@paid := @paid - total_amount, i.id, i.id)
where i.customer_id = 8
order by id /*or whatever columns determines the order of the invoices*/
;
select * from invoice;
+----+-------------+--------------+-------------+---------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+---------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 303.75 | paid |
| 3 | 8 | 200.00 | 103.75 | partial |
+----+-------------+--------------+-------------+---------+
如果你堅持要用一個觸發器,這裏是一個觸發同樣的例子:
drop table if exists invoice;
create table invoice (
id int auto_increment primary key,
customer_id int,
total_amount decimal(10,2),
paid_amount decimal(10,2) default 0,
status varchar(50) default 'unpaid'
);
insert into invoice (customer_id, total_amount) values
(3, 0),
(8, 303.75),
(8, 200.00);
drop table if exists payment;
create table payment (
id int auto_increment primary key,
customer_id int,
amount decimal(10,2)
);
delimiter $$
create trigger pay after insert on payment for each row
begin
set @paid = new.amount;
update invoice i
set
i.paid_amount = if(@paid - total_amount >= 0, total_amount, total_amount - @paid),
i.status = if(@paid - total_amount >= 0, 'paid', 'partial'),
i.id = if(@paid := @paid - total_amount, i.id, i.id)
where i.customer_id = new.customer_id
order by id;
end $$
delimiter ;
select * from invoice;
+----+-------------+--------------+-------------+--------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+--------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 0.00 | unpaid |
| 3 | 8 | 200.00 | 0.00 | unpaid |
+----+-------------+--------------+-------------+--------+
insert into payment (customer_id, amount) values (8, 400);
select * from invoice;
+----+-------------+--------------+-------------+---------+
| id | customer_id | total_amount | paid_amount | status |
+----+-------------+--------------+-------------+---------+
| 1 | 3 | 0.00 | 0.00 | unpaid |
| 2 | 8 | 303.75 | 303.75 | paid |
| 3 | 8 | 200.00 | 103.75 | partial |
+----+-------------+--------------+-------------+---------+
記住雖然,應用邏輯更容易處理,並在應用程序代碼維護,而不是在數據庫觸發器中。
我想你忘了@。試試SET amt_diff = @uni_paid_amount - t_total; –
@KayNelson我嘗試了'SET amt_diff = @uni_paid_amount - @t_total;'但我認爲'@'忽略了警告。但是現在在'ci_invoice'表中沒有更新的結果 –
如果您嘗試使用'NEW.amount'而不是變量? –