Re: Check Constraint mit Subselect

From: Rainer Lay <rainer(dot)lay(at)gmx(dot)de>
To: "A(dot) Kretschmer" <andreas(dot)kretschmer(at)schollglas(dot)com>
Cc: pgsql-de-allgemein(at)postgresql(dot)org
Subject: Re: Check Constraint mit Subselect
Date: 2008-03-11 07:54:49
Message-ID: 47D63AC9.2040603@gmx.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-de-allgemein

Moin,

wäre es in diesem Fall nicht geschickt, den Constraint auf "DEFERRABLE
INITIALLY DEFERRED" zu setzen?
Wenn ich die Doku richtig verstehe, wäre der Constraint im Rahmen der TX
zunächst nicht scharf, sondern erst beim Commit.
Vorteil: man müsste die Constraints nicht handish bei jeder TX auf
deferrable setzen.

??

Gruß
Rainer

A. Kretschmer schrieb:
> am Mon, dem 10.03.2008, um 12:15:06 +0100 mailte A. Kretschmer folgendes:
>
>> am Mon, dem 10.03.2008, um 11:46:06 +0100 mailte Thomas Guettler folgendes:
>>
>>> Hallo,
>>>
>>> Check Constraints können keine Subselects enthalten.
>>>
>>> Wie kann ich dann sicherstellen, dass es bei einer 1:N Beziehung, N
>>> nicht Null sein darf.
>>> Es muss also mindestens einen Datensatz geben.
>>>
>>> Beispiel: Zu einer Rechnung muss es immer Rechnungspositionen geben.
>>>
>> Du könntest ja eine Function aufrufen, aber Du hast dann ein
>> Henne-Ei-Problem: In dem Moment, wo Du die Rechnung erzeugst, steht in
>> der Positionstabelle noch kein Record. Man kann aber Constraints
>> deferrable setzen und in der TX das nutzen.
>>
>> Reicht das Dir weiter?
>>
>
> Mal ein Beispiel, wie sowas geht:
>
> --
> -- ich erstelle 2 Tabellen, master und slave
> --
> test=# create table master (id serial primary key, d date);
> NOTICE: CREATE TABLE will create implicit sequence "master_id_seq" for serial column "master.id"
> NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "master_pkey" for table "master"
> CREATE TABLE
> test=*# create table slave (id serial primary key, m int references master deferrable not null, i int);
> NOTICE: CREATE TABLE will create implicit sequence "slave_id_seq" for serial column "slave.id"
> NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "slave_pkey" for table "slave"
> CREATE TABLE
> --
> -- bis hier simpel, Master-Detail-Tabelle
> -- nun noch, daß kein Eintrag in master sein kann, wenn es keinen Eintrag in slave gibt
> -- dazu eine weitere Spalte via alter table, die eine Referenz auf slave darstellt
> --
> test=*# alter table master add column s int references slave deferrable not null;
> ALTER TABLE
> --
> -- nun haben wir ein Henne-Ei-Problem, das zu lösen müssen wir constraints deferred setzen
> --
> test=*# set constraints all deferred;
> SET CONSTRAINTS
> --
> -- nun können wir, innerhalb einer TX, auch mal Constraints verletzen, was wir ja tun müssen
> --
> test=*# insert into master (d,s) values (current_date,0);
> INSERT 0 1
> test=*# insert into slave(m, i) values (currval('master_id_seq'), 10);
> INSERT 0 1
> test=*# update master set s=currval('slave_id_seq') where id=currval('master_id_seq');
> UPDATE 1
> test=*# select * from master;
> id | d | s
> ----+------------+---
> 1 | 2008-03-11 | 1
> (1 row)
>
> test=*# select * from slave;
> id | m | i
> ----+---+----
> 1 | 1 | 10
> (1 row)
>
> test=*# commit;
> COMMIT
> --
> -- noch einmal, ohne daß Constraints deferred sind
> --
> test=# insert into master (d,s) values (current_date,0);
> ERROR: insert or update on table "master" violates foreign key constraint "master_s_fkey"
> DETAIL: Key (s)=(0) is not present in table "slave".
> test=!#
> --
> -- sehr schön, oder?
> --
>
>
>
>

In response to

Browse pgsql-de-allgemein by date

  From Date Subject
Next Message Thomas Guettler 2008-03-11 09:48:27 Re: Check Constraint mit Subselect
Previous Message A. Kretschmer 2008-03-11 07:44:55 Re: Check Constraint mit Subselect