
Trigger und Funktion
Hallo Liste,
hab mal wieder ein Problem, das meinen Horizont etwas überschreitet.
In einer OS Buchhaltung mit Postgresanbindung würde ich gerne etwas
mehr Verantwortung für die Datenintegrität auf die Datenbank übertr=
agen.
Ich habe eine Tabelle acc_trans, die alle im System gebuchten
Beträge beinhaltet. Jeder Buchungssatz besteht aus verschiedenen
Buchungen mit identischer id und verschiedenen Beträgen.
Tabelle acc_trans:
trans_id | amount | ...
----------+------------+----
13 | 100.00000 | ...
13 | -107.00000 | ...
13 | 7.00000 | ...
13 | 107.00000 | ...
13 | -107.00000 | ...
14 | 100.00000 | ...
14 | 7.00000 | ...
14 | -107.00000 | ...
14 | 107.00000 | ...
14 | -107.00000 | ...
... | ... | ...
Die Buchungssätze werden mittels Transaktionen in die Tabelle
acc_trans gebracht.
Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
(amount) aller Teilbuchungen (trans_id) 0 ergibt.
Wie aber weiss ich vor der Transaktion, das die Summe der
Teilbuchungen 0 ergibt?
Mit bspw. SELECT sum(amount) WHERE trans_id =3D 13 kann ich ja noch
nicht arbeiten, weil die Transaktion noch nicht commitet wurde und
ja auch vorher geprüft werden soll.
(Es stehen PL/pgSQL und PL/Perl zur Verfügung)
Vielleicht hat jemand von euch einen Tip?!
Viele Grüße
Udo Spallek
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq
Re: Trigger und Funktion
am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
> Hallo Liste,
>
> hab mal wieder ein Problem, das meinen Horizont etwas überschreitet.
>
> In einer OS Buchhaltung mit Postgresanbindung würde ich gerne etwas
> mehr Verantwortung für die Datenintegrität auf die Datenbank über=
tragen.
>
> Ich habe eine Tabelle acc_trans, die alle im System gebuchten
> Beträge beinhaltet. Jeder Buchungssatz besteht aus verschiedenen
> Buchungen mit identischer id und verschiedenen Beträgen.
>
> Tabelle acc_trans:
>
> trans_id | amount | ...
> ----------+------------+----
> 13 | 100.00000 | ...
> 13 | -107.00000 | ...
> 13 | 7.00000 | ...
> 13 | 107.00000 | ...
> 13 | -107.00000 | ...
> 14 | 100.00000 | ...
Das gibt aber hier schon ein Problem...
>
> Die Buchungssätze werden mittels Transaktionen in die Tabelle
> acc_trans gebracht.
>
> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nicht.
> Wie aber weiss ich vor der Transaktion, das die Summe der
> Teilbuchungen 0 ergibt?
Ist das nicht auch eine Frage der buchhalterischen Logig? Das sind doch
sicherlich jeweils 2 oder mehr Buchungen auf verschiedenen Konten, wo
sichergestellt sein muß, daß entweder alle oder keine erfolgt. Erfolg=
en
alle Buchungen, so ist automatisch alles richtig, oder versteh ich da
was flasch?
Wenn dem so ist, so bietet doch die 'Schutzhülle' der Transaktion übe=
r
alle nötigen Buchungen doch die Sicherheit, die Du suchst.
> Mit bspw. SELECT sum(amount) WHERE trans_id =3D 13 kann ich ja noch
> nicht arbeiten, weil die Transaktion noch nicht commitet wurde und
> ja auch vorher geprüft werden soll.
> (Es stehen PL/pgSQL und PL/Perl zur Verfügung)
>
> Vielleicht hat jemand von euch einen Tip?!
Wenn Deine Applikation weiß, daß alle Buchungen zwar getätigt, aber=
noch
nicht COMMITed wurden, kann sie ja eine Funktion aufrufen, die das
durchrechnet. In der DB selbst sehe ich keine echte Chance zu erkennen,
ob alle Buchungen erfolgt sind und ein COMMIT unmittelbar bevorsteht.
Wie gesagt, ein ON COMMIT - Trigger wäre nett...
Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org
Re: Trigger und Funktion
Hi,
A. Kretschmer schrieb:
> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nicht=
..
>
kann es eigentlich nicht geben. Alle möglichen Fehler müssen doch vor=
dem Commit auftreten. Wenn man bis zum Commit kommt sollte man auch
davon ausgehen können dass dies wirklich passiert. Was wäre denn im
Fehlerfall der Abschluss einer Transaktion (ausser commit oder
rollback)? Sonst wäre z.B. ein 2 phase commit doch gar nicht machbar.
Als Möglichkeit sehe ich da nur den vorherigen manuellen Aufruf.
Oder irre ich da?
Thomas
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Trigger und Funktion
Moin Udo,
On Wed, Mar 07, 2007 at 23:05:24 +0100, udono wrote:
> Ich habe eine Tabelle acc_trans, die alle im System gebuchten
> Beträge beinhaltet. Jeder Buchungssatz besteht aus verschiedenen
> Buchungen mit identischer id und verschiedenen Beträgen.
>
> Tabelle acc_trans:
>
> trans_id | amount | ...
> ----------+------------+----
> 13 | 100.00000 | ...
> 13 | -107.00000 | ...
> 13 | 7.00000 | ...
> 13 | 107.00000 | ...
> 13 | -107.00000 | ...
> 14 | 100.00000 | ...
> 14 | 7.00000 | ...
> 14 | -107.00000 | ...
> 14 | 107.00000 | ...
> 14 | -107.00000 | ...
> ... | ... | ...
>
> Die Buchungssätze werden mittels Transaktionen in die Tabelle
> acc_trans gebracht.
>
> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
Dazu gibt es doch bestimmt auch eine überordnete Tabelle trans in der
trans_id primary key ist. Da würde ich ansetzen.
Du könntest dort ein Feld hinzufügen, dass aussagt, ob der Buchungssa=
tz
abgeschlossen/gültig ist oder nicht.
Du legst also den Buchungssatz in trans initial mit false in dem Feld
an, fügst dann Deine Sätze in acc_trans ein und setzt das Feld danach
per UPDATE auf true.
trans hat einen Trigger ON UPDATE, der bei der Transition von
false auf true überprüft, ob die Summe 0 ist und bei <>0 das Update
abbricht.
Außerdem hat acc_trans noch einen Trigger, der UPDATE und DELETE nur
zuläßt, wenn in trans false steht. Vor =C4nderungen muss dann also t=
rans
immer false gesetzt werden.
In der Applikation dürftest Du dann nur noch die gültigen Buchungssä=
tze
betrachten.
Nicht wirklich elegant, sollte aber funktionieren.
Jürgen
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org
Re: Trigger und Funktion
> Wie aber weiss ich vor der Transaktion, das die Summe der
> Teilbuchungen 0 ergibt?
> Mit bspw. SELECT sum(amount) WHERE trans_id =3D 13 kann ich ja noch
> nicht arbeiten, weil die Transaktion noch nicht commitet wurde und
> ja auch vorher geprüft werden soll.
> (Es stehen PL/pgSQL und PL/Perl zur Verfügung)
>
> Vielleicht hat jemand von euch einen Tip?!
Hast Du schonmal dran gedacht, anstelle direkt in die Tabelle(n) zu
schreiben, das ganze über eine Stored Procedure zu machen. Also gar
nicht bis zum Trigger / Insert kommen zu lassen, sondern in der
Prozedur vorab zu überprüfen.
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate
Re: Trigger und Funktion
udono wrote:
> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
Also die offizielle SQL-Lösung wäre hier wohl eine "Assertion", die i=
n
der Art eines Check-Constraints globale Zustände prüfen kann, aber
PostgreSQL bietet das nicht an. Daher muss man hier auf jedem Fall eine
eigene Lösung basteln. Eine Prozedur/Funktion, die das Einfügen
übernimmt, wie von jemandem anders vorgeschlagen, scheint mir auch sehr=
sinnvoll.
Es ist außerdem zu beachten, dass keine der von PostgreSQL
implementierten Transaktionsisolationsmodi bei der anstehenden Prüfung
(etwa SELECT sum(amount) FROM acc_trans WHERE trans_id =3D $var) eine
korrekte Isolation bieten, weswegen die Tabelle mit SHARE ROW EXCLUSIVE
MODE manuell gesperrt werden muss.
--
Peter Eisentraut
http://developer.postgresql.org/~petere/
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
Re: Trigger und Funktion
am Thu, dem 08.03.2007, um 7:53:49 +0100 mailte Thomas Markus folgendes=
:
> Hi,
>
> A. Kretschmer schrieb:
> >IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nich=
t.
> >
> kann es eigentlich nicht geben. Alle möglichen Fehler müssen doch v=
or
> dem Commit auftreten. Wenn man bis zum Commit kommt sollte man auch
> davon ausgehen können dass dies wirklich passiert. Was wäre denn im=
> Fehlerfall der Abschluss einer Transaktion (ausser commit oder
> rollback)? Sonst wäre z.B. ein 2 phase commit doch gar nicht machbar.
> Als Möglichkeit sehe ich da nur den vorherigen manuellen Aufruf.
> Oder irre ich da?
Vermutlich. ORA hat einen ON COMMIT - Trigger, und man kann Constraints
auch auf Deferrable setzen. Manchmal sinnvoll, z.B. bei FK-Constraints.
Dann kommt auch erst direkt beim COMMIT der Fehler.
Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
Re: Trigger und Funktion
Hallo Andreas,
A. Kretschmer schrieb:
> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
> Das gibt aber hier schon ein Problem...
>> Die Buchungssätze werden mittels Transaktionen in die Tabelle
>> acc_trans gebracht.
>> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
>> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nicht=
..
Ok, dann fällt eine Lösung über Trigger wohl weg... und es wird
richtig kompliziert...
>> Wie aber weiss ich vor der Transaktion, das die Summe der
>> Teilbuchungen 0 ergibt?
> Ist das nicht auch eine Frage der buchhalterischen Logig? Das sind doch
> sicherlich jeweils 2 oder mehr Buchungen auf verschiedenen Konten, wo
> sichergestellt sein muß, daß entweder alle oder keine erfolgt. Erfo=
lgen
> alle Buchungen, so ist automatisch alles richtig, oder versteh ich da
> was flasch?
> Wenn dem so ist, so bietet doch die 'Schutzhülle' der Transaktion ü=
ber
> alle nötigen Buchungen doch die Sicherheit, die Du suchst.
Das stimmt, und das ist durch Transaktion sichergestellt. Aber
es geht mir um die Integrität der Buchnungen, deren einzelne Beträge
(amount) als Summe 0 ergeben müssen.
Klar haben wir auf der Applikationsebene Tests, die das
sicherstellen sollen. Aber das Problem bleibt bestehen, wenn
Benutzer bsw. mit psql versuchen, einzelne Buchungssätze zu
verändern, oder eben gerade die Tests auf Applikationsebene aus
irgend einem Grund fehlschlagen.
Vielen Dank und schöne Grüße
Udo Spallek
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Trigger und Funktion
Hallo Jürgen,
Jürgen E. Fischer schrieb:
> On Wed, Mar 07, 2007 at 23:05:24 +0100, udono wrote:
> Dazu gibt es doch bestimmt auch eine überordnete Tabelle trans in der
> trans_id primary key ist. Da würde ich ansetzen.
In etwa ist das so. Wir haben mehrere Tabellen ar, ap, gl die als
Primärschlüssel die id aus meiner acc_trans tragen. Aber im Prinzip
ergeben diese Tabellen zusammen, die von dir beschriebene Tabelle
trans.
> Du könntest dort ein Feld hinzufügen, dass aussagt, ob der Buchungs=
satz
> abgeschlossen/gültig ist oder nicht.
> Du legst also den Buchungssatz in trans initial mit false in dem Feld
> an, fügst dann Deine Sätze in acc_trans ein und setzt das Feld dana=
ch
> per UPDATE auf true.
Ja, damit könnte ich die Transaktionssicherheit noch etwas verbessern..=
..
> trans hat einen Trigger ON UPDATE, der bei der Transition von
> false auf true überprüft, ob die Summe 0 ist und bei <>0 das Update
> abbricht.
.... ach, ok ich verstehe. Das hört sich auf jeden Fall gut an.
Aber dann habe ich in der acc_trans immer noch Buchungen stehen, die
ungültig sein können. Gut, der Trigger in trans ließe sich bestimmt=
erweitern auf ein anschließendes Delete der fehlerhaften
Transaktionen...
> Außerdem hat acc_trans noch einen Trigger, der UPDATE und DELETE nur
> zuläßt, wenn in trans false steht. Vor =C4nderungen muss dann also=
trans
> immer false gesetzt werden.
Ok, lauter gute Ideen!
Delete ist noch eine Thema für sich. Denn in der Buchhaltung gibt es
kein löschen von Daten als solches, sondern eher ein Storno, was ich
aber auch gern von der Datenbank verwaltet wissen würde (On delete
trigger).
> In der Applikation dürftest Du dann nur noch die gültigen Buchungss=
ätze
> betrachten.
> Nicht wirklich elegant, sollte aber funktionieren.
Bestens, vielen Dank! Deinen Ansatz werde ich mal austesten.
Viele Grüße
Udo Spallek
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Trigger und Funktion
Hi Matthias,
Matthias Zirngibl schrieb:
>> Wie aber weiss ich vor der Transaktion, das die Summe der
>> Teilbuchungen 0 ergibt?
>> Mit bspw. SELECT sum(amount) WHERE trans_id =3D 13 kann ich ja noch
>> nicht arbeiten, weil die Transaktion noch nicht commitet wurde und
>> ja auch vorher geprüft werden soll.
>> (Es stehen PL/pgSQL und PL/Perl zur Verfügung)
>> Vielleicht hat jemand von euch einen Tip?!
> Hast Du schonmal dran gedacht, anstelle direkt in die Tabelle(n) zu
> schreiben, das ganze über eine Stored Procedure zu machen.
Ja hab ich - mit Grauen :-) Ich dacht das irgendwie umschiffen zu
können, weil ich noch keinerlei Erfahrung mit Stored Procedures
habe. Auch die Sache mit den vielen Apostrophen macht mir difusee
Gänsehaut... aber ich befürchte, das ist der einzig verbleibende Weg
und ich werde mich wohl mal reinknien müssen...
> Also gar
> nicht bis zum Trigger / Insert kommen zu lassen, sondern in der
> Prozedur vorab zu überprüfen.
Ja letztendlich ist das die von mir gewünschte Funktionsweise: Erst
die Integrität der Datensätze überprüfen (Summe amount =3D 0), un=
d
dann entweder INSERT / UPDATE ausführen oder Fehler auslösen.
Dazu werde ich mich sicher nochmal melden...
Vielen Dank.
Viele Grüße Udo
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster
Re: Trigger und Funktion
>
> Delete ist noch eine Thema für sich. Denn in der Buchhaltung
> gibt es kein löschen von Daten als solches, sondern eher ein
> Storno, was ich aber auch gern von der Datenbank verwaltet
> wissen würde (On delete trigger).
dafuer eignen sich meiner meinung nach nun mal RULES am besten, um das
delete komplett um zu schreiben
ala
....ON DELETE TO bar.tbl_foo DO INSTEAD UPDATE bar.tbl_foo SET geloescht =3D
true
WHERE tbl_foo.id =3D old.id;
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate
Re: Trigger und Funktion
udono <udono [at] gmx.net> schrieb:
> >>Vielleicht hat jemand von euch einen Tip?!
> >Hast Du schonmal dran gedacht, anstelle direkt in die Tabelle(n) zu
> >schreiben, das ganze über eine Stored Procedure zu machen.
> Ja hab ich - mit Grauen :-) Ich dacht das irgendwie umschiffen zu kön=
nen,
> weil ich noch keinerlei Erfahrung mit Stored Procedures habe. Auch die
> Sache mit den vielen Apostrophen macht mir difusee Gänsehaut... aber =
ich
*lach*
Das ist mit dem Dollar-Quoting seit 8.0 /deutlich/ leichter geworden.
> befürchte, das ist der einzig verbleibende Weg und ich werde mich woh=
l mal
> reinknien müssen...
Sich damit, also z.B. plpgsql, zu beschäftigen ist eine Investition, di=
e
sich lohnt. Das brauchst Du ja z.B. auch für TRIGGER.
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster
Re: Trigger und Funktion
A. Kretschmer writes:
> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
>> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
>> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
>
>
> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nicht=
..
Hm, wenn man das "It is not intended for general use" in der Doku zu
"create constraint trigger" überliest, kann man damit scheinbar den
gewünschten Effekt erzielen:
--8<---------------cut here---------------start------------->8---
create table acc_trans(trans_id int, amount numeric);
create function check_balance() returns trigger as $$
begin
if tg_op =3D 'DELETE' or tg_op =3D 'UPDATE' then
if (select sum(amount) from acc_trans
where trans_id =3D old.trans_id)
<> 0 then
raise exception 'invalid balance';
end if;
end if;
if tg_op =3D 'INSERT' or tg_op =3D 'UPDATE' then
if (select sum(amount) from acc_trans
where trans_id =3D new.trans_id)
<> 0 then
raise exception 'invalid balance';
end if;
end if;
return new;
end
$$ language 'plpgsql';
create constraint trigger check_balance
after update or insert or delete
on acc_trans initially deferred
for each row execute procedure check_balance();
--8<---------------cut here---------------end--------------->8---
Gruß
Andreas
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster
Re: Trigger und Funktion
Moin Udo,
On Thu, Mar 08, 2007 at 13:03:27 +0100, udono wrote:
> >trans hat einen Trigger ON UPDATE, der bei der Transition von
> >false auf true überprüft, ob die Summe 0 ist und bei <>0 das Updat=
e
> >abbricht.
> ... ach, ok ich verstehe. Das hört sich auf jeden Fall gut an.
> Aber dann habe ich in der acc_trans immer noch Buchungen stehen, die
> ungültig sein können. Gut, der Trigger in trans ließe sich bestim=
mt
> erweitern auf ein anschließendes Delete der fehlerhaften
> Transaktionen...
Nach dem gescheiterten UPDATE muß ja ein ROLLBACK folgen und acc_trans
ist wieder sauber.
> >Außerdem hat acc_trans noch einen Trigger, der UPDATE und DELETE nur
> >zuläßt, wenn in trans false steht. Vor =C4nderungen muss dann als=
o trans
> >immer false gesetzt werden.
INSERT betrifft das natürlich genauso.
> Delete ist noch eine Thema für sich. Denn in der Buchhaltung gibt es
> kein löschen von Daten als solches, sondern eher ein Storno, was ich
> aber auch gern von der Datenbank verwaltet wissen würde (On delete
> trigger).
Wenn dem so ist, könnte man die stornierten Buchungen auch in acc_trans
belassen und dem Status gültig/ungültig noch storniert hinzufügen.
Jürgen
--
<revenger#postgresql> huhm is it really normal that many students are una=
ble to fixate a plug in a wall?
<dennisb#postgresql> revenger: it sounds like a hardware problem to me...
<Erwin#postgresql> dennisb: That's what you software guys always say!
<dennisb#postgresql> exactly :-)
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Trigger und Funktion
Andreas Seltenreich <andreas+pg [at] gate450.dyndns.org> schrieb:
> > IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nic=
ht.
>
> Hm, wenn man das "It is not intended for general use" in der Doku zu
> "create constraint trigger" überliest, kann man damit scheinbar den
> gewünschten Effekt erzielen:
[ coolen Code gesnippt ]
Cool.
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq
Re: Trigger und Funktion
--On Donnerstag, M=C3=A4rz 08, 2007 13:20:24 +0100 Andreas Seltenreich
<andreas+pg [at] gate450.dyndns.org> wrote:
> A. Kretschmer writes:
>
>> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
>>> Es soll die Regel gelten, dass nur Buchungss=C3=A4tze in die Tabelle
>>> acc_trans d=C3=BCrfen (UPDATE, INSERT), deren Summe der Einzelbetr=C3=
=A4ge
>>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
>>
>>
>> IMHO w=C3=A4re hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nic=
ht.
>
> Hm, wenn man das "It is not intended for general use" in der Doku zu
> "create constraint trigger" =C3=BCberliest, kann man damit scheinbar den
> gew=C3=BCnschten Effekt erzielen:
>
Hmm, an sich clever, aber ich sehe nicht wie man damit das
Konsistenzproblem mit mehreren gleichzeitigen Transaktionen l=C3=B6sen kann=
..
Ferner sollte man beachten, dass Deferred Trigger bei sehr gro=C3=9Fen
Transaktionen schnell ein Speicherproblem verursachen k=C3=B6nnen. Um das=
wirklich 'sicher' abzuwickeln kommt man um die n=C3=B6tige Serialisierung=
mittels Peter's vorgeschlagener Methode mit expliziten Locks nicht
drumherum, f=C3=BCrchte ich.....
--
Thanks
Bernd
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings
Re: Trigger und Funktion
Hallo Andreas,
Andreas Seltenreich schrieb:
> A. Kretschmer writes:
>> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
>>> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
>>> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
>>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
>> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nich=
t.
> Hm, wenn man das "It is not intended for general use" in der Doku zu
> "create constraint trigger" überliest, kann man damit scheinbar den
> gewünschten Effekt erzielen:
Hui, das sieht verdammt gut aus! Klasse, vielen Dank!
So jetzt erstmal Postgres 8 installieren, meine 7.4.9 kann das so
nicht umsetzen.
Mit den anderen Programmierern und der Community werde ich noch
besprechen müssen, ob wir für die nächste Version von lx-office
postgres >=3D 8.0 voraussetzen können...
> --8<---------------cut here---------------start------------->8---
> create table acc_trans(trans_id int, amount numeric);
>
> create function check_balance() returns trigger as $$
[...]
> create constraint trigger check_balance
> after update or insert or delete
> on acc_trans initially deferred
> for each row execute procedure check_balance();
Wow, constraint trigger ...
Das sieht tatsächlich so aus, als könnte es funktionieren.
Ich werde es die nächsten Wochen mal testen und weiter Bericht
erstatten.
Auch die Hinweise von Peter und Bernd mit dem expliz. Lock werde ich
beachten.
Vielen Dank nochmal an euch alle!
Bis bald
Udo Spallek
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
Re: Trigger und Funktion
Bernd Helmle writes:
> --On Donnerstag, März 08, 2007 13:20:24 +0100 Andreas Seltenreich <an=
dreas+pg [at] gate450.dyndns.org> wrote:
>> A. Kretschmer writes:
>>> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
>>>> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
>>>> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
>>>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
>>>
>>> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nic=
ht.
>>
>> Hm, wenn man das "It is not intended for general use" in der Doku zu
>> "create constraint trigger" überliest, kann man damit scheinbar den
>> gewünschten Effekt erzielen:
>
> Hmm, an sich clever, aber ich sehe nicht wie man damit das
> Konsistenzproblem mit mehreren gleichzeitigen Transaktionen lösen
> kann.
Mir ist klar, daß die Aggregatfunktion selbst beim maximalen
Isolationslevel andere Tupel zu sehen bekommt, als dies bei echter
serieller Ausführung der Fall wäre, aber kann das bei meinem Beispiel
tatsächlich zu Inkonsistenzen führen?
Ich sehe im Moment nicht einmal, wie hier non-repeatable- oder
phantom-reads zu inkonsistenten Daten führen könnten, da durch den
Trigger garantiert wird, daß für nebenläufig committete Tupel
ebenfalls sum(amount) =3D 0 gilt, und sie somit keinen Einfluß auf das
Ergebnis der Konsistenzbedingung im Trigger einer zu committenden
Transaktion haben können.
Oder bin ich hier auf dem Holzweg?
Gruß
Andreas
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings
Re: Trigger und Funktion
This is a multi-part message in MIME format.
--------------040906060105020702090703
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Hm,
ich kann keinen on commit trigger in der ora doku finden. Irgendwo einen
link parat?
|das deferrable an constraints wirkt nur auf subtransactions sofern ich
die doku richtig verstanden habe.
thomas
|
A. Kretschmer schrieb:
> am Thu, dem 08.03.2007, um 7:53:49 +0100 mailte Thomas Markus folgend=
es:
>
>> Hi,
>>
>> A. Kretschmer schrieb:
>>
>>> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nic=
ht.
>>>
>>>
>> kann es eigentlich nicht geben. Alle möglichen Fehler müssen doch =
vor
>> dem Commit auftreten. Wenn man bis zum Commit kommt sollte man auch
>> davon ausgehen können dass dies wirklich passiert. Was wäre denn i=
m
>> Fehlerfall der Abschluss einer Transaktion (ausser commit oder
>> rollback)? Sonst wäre z.B. ein 2 phase commit doch gar nicht machbar=
..
>> Als Möglichkeit sehe ich da nur den vorherigen manuellen Aufruf.
>> Oder irre ich da?
>>
>
> Vermutlich. ORA hat einen ON COMMIT - Trigger, und man kann Constraints
> auch auf Deferrable setzen. Manchmal sinnvoll, z.B. bei FK-Constraints.
> Dann kommt auch erst direkt beim COMMIT der Fehler.
>
>
> Andreas
>
--
Thomas Markus
Tel: +49 30 29 36 399 - 22
Fax: +49 30 29 36 399 - 50
Mail: t.markus [at] proventis.net
Web: http://www.proventis.net
Web: http://www.blue-ant.de
proventis GmbH
Zimmerstraße 79-80
10117 Berlin
Geschäftsführer: Norman Frischmuth
Sitz: Berlin
Handelsregister: AG Berlin-Charlottenburg, HR 82917
We support your project business!
--------------040906060105020702090703
Content-Type: text/x-vcard; charset=utf-8;
name="t.markus.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="t.markus.vcf"
begin:vcard
fn:Thomas Markus
n:Markus;Thomas
org:proventis GmbH
adr;dom:;;Zimmerstr. 79-80;Berlin;Berlin;10117
email;internet:t.markus [at] proventis.net
tel;work:+49 30 29 36 399 22
x-mozilla-html:FALSE
url:http://www.proventis.net
version:2.1
end:vcard
--------------040906060105020702090703
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings
--------------040906060105020702090703--
Re: Trigger und Funktion
Thomas Markus <t.markus [at] proventis.net> schrieb:
> Hm,
>
> ich kann keinen on commit trigger in der ora doku finden. Irgendwo eine=
n
> link parat?
=C4hm, nö.
Mir war so, sowas mal früher gelesen zu haben, und ein Googeln nach
on-commit trigger bringt auch einiges an Hinweisen, aber ich hab dazu
keine direkte Doku gefunden, sorry.
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings
Re: Trigger und Funktion
Hallo Andreas,
A. Kretschmer schrieb:
> am Wed, dem 07.03.2007, um 23:05:24 +0100 mailte udono folgendes:
> Das gibt aber hier schon ein Problem...
>> Die Buchungssätze werden mittels Transaktionen in die Tabelle
>> acc_trans gebracht.
>> Es soll die Regel gelten, dass nur Buchungssätze in die Tabelle
>> acc_trans dürfen (UPDATE, INSERT), deren Summe der Einzelbeträge
>> (amount) aller Teilbuchungen (trans_id) 0 ergibt.
> IMHO wäre hier ein ON COMMIT TRIGGER sinnvoll. Haben wir leider nicht=
..
Ok, dann fällt eine Lösung über Trigger.
>> Wie aber weiss ich vor der Transaktion, das die Summe der
>> Teilbuchungen 0 ergibt?
> Ist das nicht auch eine Frage der buchhalterischen Logig? Das sind doch
> sicherlich jeweils 2 oder mehr Buchungen auf verschiedenen Konten, wo
> sichergestellt sein muß, daß entweder alle oder keine erfolgt. Erfo=
lgen
> alle Buchungen, so ist automatisch alles richtig, oder versteh ich da
> was flasch?
> Wenn dem so ist, so bietet doch die 'Schutzhülle' der Transaktion ü=
ber
> alle nötigen Buchungen doch die Sicherheit, die Du suchst.
Das stimmt, und das ist durch die Transaktion sichergestellt. Aber
es geht mir um die Integrität der einzelnen Beträge (amount), die
als Summe 0 ergeben müssen.
Klar haben wir auf der Applikationsebene Tests, die das
sicherstellen sollen. Aber das Problem bleibt bestehen, wenn
Benutzer bsw. mit psql versuchen, einzelne Buchungssätze zu
verändern, oder eben gerade die Tests auf Applikationsebene aus
irgend einem Grund fehlschlagen.
Vielen Dank und schöne Grüße
Udo Spallek
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org
Re: Trigger und Funktion
Am Donnerstag, 8. März 2007 15:23 schrieb Andreas Seltenreich:
> Ich sehe im Moment nicht einmal, wie hier non-repeatable- oder
> phantom-reads zu inkonsistenten Daten führen könnten, da durch den
> Trigger garantiert wird, daß für nebenläufig committete Tupel
> ebenfalls sum(amount) =3D 0 gilt, und sie somit keinen Einfluß auf da=
s
> Ergebnis der Konsistenzbedingung im Trigger einer zu committenden
> Transaktion haben können.
Es kann sein, dass man in diesem konkreten Fall in der Tat ohne auskommt,=
da
die Integritätsbedingung der Gesamttabelle (sum =3D 0) durch die
Integritätsbedingung einer Transaktion (sum =3D 0) erhalten wird. Zumin=
dest
könnte man mit Aussicht auf Erfolg versuchen, das zu beweisen.
Das Gegenbeispiel wäre, wenn die Gesamtbedingung für die Tabelle sum =
> 0 wäre
und keine Bedingung an die Transaktion gestellt wird (weil zum Beispiel
Umbuchen durchgeführt werden können). Dann kommt man ohne Locks nicht=
aus.
--
Peter Eisentraut
http://developer.postgresql.org/~petere/
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate
Re: Trigger und Funktion
--==========ED4BE9BD87AFA7C12DF2==========
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Hi,
halb OT, aber das sollte nochmal gesagt werden:
-- udono <udono [at] gmx.net> wrote:
> Mit den anderen Programmierern und der Community werde ich noch
> besprechen müssen, ob wir für die nächste Version von lx-office
> postgres >=3D 8.0 voraussetzen können...
hmmm, wichtiger wäre es, wenn ihr die ganzen SQL-Injection-Lücken
rauswerfen und den Code aufräumen würdet (Fehlerreport ging an die auf
der Website angegebenen E-mail-Adressen).
So schlechten Perl-Code habe ich schon lange nicht mehr gesehen -- und
dabei macht es gerade Perl dem Entwickler einfach, den Code mittels POD zu
dokumentieren und mit den hervorragenden Testing-Libraries zu testen.
Mein Tipp:
Neu schreiben und dafür sorgen, dass es auf aktuellem CPAN-Niveau steht.
Das Buch "Perl Best Practices" ist dafür ein ganz guter Einstieg.
Ciao
Alvar
--
** Alvar C.H. Freude, http://alvar.a-blast.org/
** http://www.wen-waehlen.de/
** http://odem.org/
**=A0http://www.assoziations-blaster.de/
--==========ED4BE9BD87AFA7C12DF2==========
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQFF9DMZOndlH63J86wRAi3VAJ4/4BZJ1bnNV5qGgMehjyRJQw1KpgCg zw58
SKh46Pm6hGFE4ekZWa0NajU=
=y8i+
-----END PGP SIGNATURE-----
--==========ED4BE9BD87AFA7C12DF2==========--
Re: Trigger und Funktion
In article <3B4D3B59B35719973492897B-PDEa3EQ435vqxUbn4Il/nazUEOm+Xw19 [at] public.gmane.org>,
Alvar Freude <alvar-8X5/x1FUHTdAfugRpC6u6w [at] public.gmane.org> writes:
> Hi,
> halb OT, aber das sollte nochmal gesagt werden:
> -- udono <udono-hi6Y0CQ0nG0 [at] public.gmane.org> wrote:
>> Mit den anderen Programmierern und der Community werde ich noch
>> besprechen müssen, ob wir für die nächste Version von lx-office
>> postgres >=3D 8.0 voraussetzen können...
> hmmm, wichtiger wäre es, wenn ihr die ganzen SQL-Injection-Lücken
> rauswerfen und den Code aufräumen würdet (Fehlerreport ging an die auf
> der Website angegebenen E-mail-Adressen).
> So schlechten Perl-Code habe ich schon lange nicht mehr gesehen -- und
> dabei macht es gerade Perl dem Entwickler einfach, den Code mittels POD zu
> dokumentieren und mit den hervorragenden Testing-Libraries zu testen.
Und durch konsequente Verwendung von sowas wie
my $res =3D $dbh->selectall_arrayref(q{
SELECT foo, bar
FROM customers
WHERE id =3D ?
}, undef, $id);
sollten auch keine SQL-Injection-Lücken mehr auftreten, oder?
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: Trigger und Funktion
am Sun, dem 11.03.2007, um 17:49:29 +0100 mailte Alvar Freude folgendes:
> Hi,
>
> halb OT, aber das sollte nochmal gesagt werden:
>
> -- udono <udono [at] gmx.net> wrote:
>
> > Mit den anderen Programmierern und der Community werde ich noch
> > besprechen müssen, ob wir für die nächste Version von lx-office
> > postgres >=3D 8.0 voraussetzen können...
>
> hmmm, wichtiger wäre es, wenn ihr die ganzen SQL-Injection-Lücken
> rauswerfen und den Code aufräumen würdet (Fehlerreport ging an die =
auf
> der Website angegebenen E-mail-Adressen).
Ich will ja jetzt nicht eins nachsetzen oder so, aber mir ist ein
Anwender von lx-office bekannt, der mir berichtetet, daß er es über h=
at,
weil, und ich plappere jetzt nur nach, von Version zu Version es nur
Probleme gab, Datenübernahme zwischen Versionen nicht gehen würde und=
das
Programm so nicht verwendbar sei.
Ob dem so ist, kann ich absolut nicht beurteilen. Ist auch schon eine
Weile her, wo ich das vernahm, mußte halt nur eben daran denken, als ic=
h
Alvars Mail las. Aber falls udono da Connetions (wie auch immer) zu den
Machern davon hat, vielleicht hilft ja auch mal negatives Feedback wie
dieses...
Falls SQL-Injection-Lücken ein Problem sind, ein Tipp: Prepared
Statements können die Schmerzen lindern.
Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo [at] postgresql.org so that your
message can get through to the mailing list cleanly
Re: Trigger und Funktion
--==========DA162FADB40976FEB145==========
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Hi,
-- Harald Fuchs <hf0217x [at] protecting.net> wrote:
> Und durch konsequente Verwendung von sowas wie
>
> my $res =3D $dbh->selectall_arrayref(q{
> SELECT foo, bar
> FROM customers
> WHERE id =3D ?
> }, undef, $id);
>
> sollten auch keine SQL-Injection-Lücken mehr auftreten, oder?
genau, damit ist SQL-Injection sicher ausgeschlossen. Im schlimmsten Falle
meckert PostgreSQL, dass "0 or 1=3D1" keine Zahl sei ;-)
Ciao
Alvar
--
** Alvar C.H. Freude, http://alvar.a-blast.org/
**=A0http://www.assoziations-blaster.de/
** http://www.wen-waehlen.de/
** http://odem.org/
--==========DA162FADB40976FEB145==========
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQFF9HgLOndlH63J86wRAuzdAJwLzG2XHUP19kuCQbtNUF5stAh/8QCg gVnx
QLW7HBtWO8T1E0axruTnGS8=
=MZmE
-----END PGP SIGNATURE-----
--==========DA162FADB40976FEB145==========--
Re: Trigger und Funktion
--==========CE347787E748EF3B0EE4==========
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Hallo,
-- "A. Kretschmer" <andreas.kretschmer [at] schollglas.com> wrote:
> Ich will ja jetzt nicht eins nachsetzen oder so, aber mir ist ein
> Anwender von lx-office bekannt, der mir berichtetet, daß er es über =
hat,
> weil, und ich plappere jetzt nur nach, von Version zu Version es nur
> Probleme gab, Datenübernahme zwischen Versionen nicht gehen würde und
> das Programm so nicht verwendbar sei.
sagen wir mal so: ich kann es mir sehr gut vorstellen.
Ich habe für den letzten Perl-Workshop einen Vortrag über gut
Programmierpraktiken gehalten, LX-Office war dabei (leider!) mein großes
Negativbeispiel. Es macht so gut wie alles falsch was geht: kaum
Kommentare/keinerlei POD, keine Tests, ausgeschaltete Warnungen, kein
Strict-Mode (das sind nun vier der schlimmsten Sünden, die man in der
Perl-Community machen kann), komische Struktur, globale Variablen,
inkonsistente Benennung von Variablen und Modulen, SQL mit direkten
ungefilterten Eingabeparametern (dabei wäre es via Bind-Variablen trivial
zu vermeiden), Vermengung von Code und HTML und so weiter.
Klar, da sind viele Altlasten. Ich kenne das, ich habe auch ein paar
ähnliche Altlasten (die ich bei dem Vortrag ebenfalls als Negativbeispiel
gezeigt habe ;) ). Aber irgendwann muss man mal den Mut fassen einfach
alles neu zu bauen.
> Falls SQL-Injection-Lücken ein Problem sind, ein Tipp: Prepared
> Statements können die Schmerzen lindern.
.... wenn man Bind-Variablen nutzt. Das ist auch der normalerweise übliche
Weg unter Perl ...
Ciao
Alvar
--
** Alvar C.H. Freude, http://alvar.a-blast.org/
**=A0http://www.assoziations-blaster.de/
** http://www.wen-waehlen.de/
** http://odem.org/
--==========CE347787E748EF3B0EE4==========
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQFF9HzCOndlH63J86wRArbxAJ9V/GhTUMX9pbqJM6GX69qzPlEzqgCg kTq7
JEqsY9yk0+la4XfGkkocjd0=
=yn9c
-----END PGP SIGNATURE-----
--==========CE347787E748EF3B0EE4==========--