Doppelte Buchführung ist
eine Reihe von Regeln für die Erfassung von Finanzinformationen in einem Finanzbuchhaltungssystem, in dem jede Transaktion oder jedes Ereignis mindestens zwei verschiedene nominale Sachkonten ändert.
Ein Konto kann "belastet" oder "gutgeschrieben" werden, und die Summe aller Gutschriften muss gleich der Summe aller Belastungen sein.
Wie würden Sie dies in einer Postgres-Datenbank implementieren? Angabe der folgenden 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'))
);
Hinweis: In der Tabelle transaction_details wird kein explizites Debit- / Kreditkonto angegeben, da das System in der Lage sein sollte, mehr als ein Konto in einer einzelnen Transaktion zu belasten / gutzuschreiben.
Diese DDL schafft die folgende Anforderung: Nachdem eine Datenbanktransaktion für die Tabelle transaction_details festgeschrieben wurde, muss sie für jeden den gleichen Betrag belasten und gutschreiben transaction_id
, z .
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;
Ist es möglich, dies in einer PostgreSQL-Datenbank zu implementieren? Ohne Angabe zusätzlicher Tabellen zum Speichern von Triggerzuständen.