| | 1 | = Автоматско ажурирање на баланс на трансакциска сметка |
| | 2 | |
| | 3 | ==== Опис |
| | 4 | Овој тригер овозможува автоматско ажурирање на балансот (`balance`) на трансакциските сметки при секоја промена во табелата `transaction_breakdown` |
| | 5 | |
| | 6 | Секој запис во `transaction_breakdown` претставува: |
| | 7 | - приход (`earned_amount`) |
| | 8 | - трошење (`spent_amount`) |
| | 9 | |
| | 10 | Тригерот гарантира дека балансот на сметката секогаш ја рефлектира реалната состојба по секоја трансакција |
| | 11 | |
| | 12 | ==== Табели опфатени со тригерот |
| | 13 | - transaction_account |
| | 14 | - transaction_breakdown |
| | 15 | |
| | 16 | ==== Тип на тригер |
| | 17 | - AFTER INSERT |
| | 18 | - AFTER UPDATE |
| | 19 | - AFTER DELETE |
| | 20 | Активиран над табелата `transaction_breakdown` |
| | 21 | |
| | 22 | ==== SQL Код |
| | 23 | {{{#!sql |
| | 24 | CREATE OR REPLACE FUNCTION update_transaction_account_balance() |
| | 25 | RETURNS TRIGGER |
| | 26 | LANGUAGE plpgsql |
| | 27 | AS $$ |
| | 28 | BEGIN |
| | 29 | -- При бришење на запис (rollback на ефектот) |
| | 30 | IF TG_OP = 'DELETE' THEN |
| | 31 | UPDATE transaction_account |
| | 32 | SET balance = balance - OLD.earned_amount + OLD.spent_amount |
| | 33 | WHERE transaction_account_id = OLD.transaction_account_id; |
| | 34 | |
| | 35 | -- При додавање на нов запис |
| | 36 | ELSIF TG_OP = 'INSERT' THEN |
| | 37 | UPDATE transaction_account |
| | 38 | SET balance = balance + NEW.earned_amount - NEW.spent_amount |
| | 39 | WHERE transaction_account_id = NEW.transaction_account_id; |
| | 40 | |
| | 41 | -- При ажурирање на постоечки запис |
| | 42 | ELSIF TG_OP = 'UPDATE' THEN |
| | 43 | UPDATE transaction_account |
| | 44 | SET balance = balance |
| | 45 | - OLD.earned_amount + OLD.spent_amount |
| | 46 | + NEW.earned_amount - NEW.spent_amount |
| | 47 | WHERE transaction_account_id = NEW.transaction_account_id; |
| | 48 | END IF; |
| | 49 | |
| | 50 | RETURN NULL; |
| | 51 | END; |
| | 52 | $$; |
| | 53 | |
| | 54 | |
| | 55 | CREATE TRIGGER trg_update_transaction_account_balance |
| | 56 | AFTER INSERT OR UPDATE OR DELETE |
| | 57 | ON transaction_breakdown |
| | 58 | FOR EACH ROW |
| | 59 | EXECUTE FUNCTION update_transaction_account_balance(); |
| | 60 | }}} |
| | 61 | |
| | 62 | ==== Објаснување на логиката |
| | 63 | `DELETE`: |
| | 64 | - Се поништува ефектот од избришаниот запис |
| | 65 | |
| | 66 | `INSERT`: |
| | 67 | - Приходите се додаваат на балансот |
| | 68 | - Трошоците се одземаат од балансот |
| | 69 | |
| | 70 | `UPDATE`: |
| | 71 | - Прво се поништува стариот ефект |
| | 72 | - Потоа се применува новиот ефект |
| | 73 | |
| | 74 | |
| | 75 | ==== Причина за користење |
| | 76 | Овој тригер е клучен затоа што: |
| | 77 | - `balance` е динамичка и критична вредност |
| | 78 | - рачно ажурирање е ризично |
| | 79 | - апликацијата не смее да биде единствен извор на вистина |
| | 80 | - базата ја контролира финансиската логика |
| | 81 | - се елиминираат грешки при ажурирање и бришење |