La contabilità a doppia entrata è
un insieme di regole per la registrazione di informazioni finanziarie in un sistema di contabilità finanziaria in cui ogni transazione o evento modifica almeno due diversi conti contabili.
Un conto può essere "addebitato" o "accreditato" e la somma di tutti i crediti deve essere uguale alla somma di tutti i debiti.
Come lo implementereste in un database Postgres? Specifica del seguente DDL:
CREATE TABLE accounts(
account_id serial NOT NULL PRIMARY KEY,
account_name varchar(64) NOT NULL
);
CREATE TABLE transactions(
transaction_id serial NOT NULL PRIMARY KEY,
transaction_date date NOT NULL
);
CREATE TABLE transactions_details(
id serial8 NOT NULL PRIMARY KEY,
transaction_id integer NOT NULL
REFERENCES transactions (transaction_id)
ON UPDATE CASCADE
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
account_id integer NOT NULL
REFERENCES accounts (account_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
NOT DEFERRABLE INITIALLY IMMEDIATE,
amount decimal(19,6) NOT NULL,
flag varchar(1) NOT NULL CHECK (flag IN ('C','D'))
);
Nota: la tabella transazione_dettagli non specifica un conto di addebito / credito esplicito, poiché il sistema dovrebbe essere in grado di addebitare / accreditare più di un conto in una singola transazione.
Questo DDL crea il seguente requisito: Dopo che una transazione del database si è impegnata nella tabella transazioni_dettagli, deve addebitare e accreditare lo stesso importo per ciascuno transaction_id
, ad esempio :
INSERT INTO accounts VALUES (100, 'Accounts receivable');
INSERT INTO accounts VALUES (200, 'Revenue');
INSERT INTO transactions VALUES (1, CURRENT_DATE);
-- The following must succeed
BEGIN;
INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '1000'::decimal, 'C');
COMMIT;
-- But this must raise some error
BEGIN;
INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '500'::decimal, 'C');
COMMIT;
È possibile implementarlo in un database PostgreSQL? Senza specificare tabelle aggiuntive per memorizzare gli stati di trigger.