Simulation von Radio-Buttons

Hallo Profis
Irgendwie krieg ich’s nicht gebacken, evtl. kann mir einer von Euch weiterhelfen:
Zwei Tabellen:
CREATE tb_master(tag serial PRIMARY kEY, […weitere Ferlder…]);
CREATE tb_detail(tb_master_tag INTEGER REFERENCES tb_master(tag),preferred_name BOOLEAN,[…noch mehr Felder…]);
Wie man sieht, ist das eine handelsübliche 1:n Beziehung, also nichts dramatisches.
In der Detailtabelle möchte ich nun folgendes erreichen: Alle einer Zeile der Master-Tabelle zugeordneten Zeilen
der Detail-Tabelle sollen in der Spalte “preferred_name” genau einmal TRUE sein, sonst FALSE.
Wird eine Zeile mit preferred_name=true eingefügt, so müssen alle anderen Zeilen auf false gesetzt werden.
In der zuerst eingefügten Zeile muss preferred_name=TRUE sein. Wird in einer Zeile preferred_name auf FALSE gesetzt, dann darf die
Änderung nicht akzeptiert werden, wenn der ursprügliche Wert TRUE war.
Ich möchte also das Verhalten einer Gruppe von Radio-Buttons simulieren…
Schaut Euch mal an, was mir dazu eingefallen ist:

CREATE TABLE tb_manufacturer(
tag serial NOT NULL,
logofile character varying(255),
website character varying(255),
support_mail character varying(100),
support_phone character varying(40),
support_adress text,
CONSTRAINT pk_manufactuer PRIMARY KEY (tag));
CREATE TABLE tb_possible_manufacturer_name(
tb_manufacturer_tag integer NOT NULL,
ps_name character varying(100) NOT NULL,
preferred_name boolean,
CONSTRAINT fk_manufacturer FOREIGN KEY (tb_manufacturer_tag) REFERENCES tb_manufacturer (tag) ON DELETE CASCADE);  
 
CREATE TRIGGER trg_preferred_manufacturer_name_ins BEFORE INSERT ON tb_possible_manufacturer_name
FOR EACH ROW EXECUTE PROCEDURE trfk_check_preferred_name();
CREATE TRIGGER trg_preferred_manufacturer_name_upd BEFORE UPDATE ON tb_possible_manufacturer_name
FOR EACH ROW EXECUTE PROCEDURE trfk_check_preferred_name();
CREATE OR REPLACE FUNCTION trfk_check_preferred_name() RETURNS "trigger" AS
$BODY$
BEGIN
--der ERSTE Datensatz MUSS true sein...
IF (SELECT COUNT(*) FROM tb_possible_manufacturer_name WHERE NEW.tb_manufacturer_tag=tb_manufacturer_tag) = 0 THEN
 NEW.preferred_name:=TRUE;
 RETURN NEW;
END IF;
--Wenn einer true, dann alle anderen auf false, egal ob update oder insert
IF (NEW.preferred_name=TRUE) THEN
 UPDATE tb_possible_manufacturer_name SET preferred_name=FALSE WHERE tb_manufacturer_tag=NEW.tb_manufacturer_tag AND tb_language_tag=NEW.tb_language_tag;
 RETURN NEW;
END IF;
IF (TG_OP='UPDATE') THEN
  IF ((NEW.preferred_name=FALSE) AND (OLD.preferred_name=TRUE)) THEN
   RETURN NULL;
  END IF; 
 RETURN NEW; 
END IF;
/*
IF (NEW.preferred_name=FALSE) THEN
 IF NOT TRUE IN (SELECT preferred_name FROM tb_possible_manufacturer_name WHERE tb_manufacturer_tag=NEW.tb_manufacturer_tag AND tb_language_tag=NEW.tb_language_tag) THEN
  NEW.preferred_name=TRUE; 
 END IF; 
END IF;
*/
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
INSERT INTO tb_manufacturer(1,NULL,NULL,NULL,NULL,NULL);
INSERT INTO tb_possible_manufacturer_name(tb_manufacturer_tag,ps_name,preferred_name)
VALUES(1,'HP',false);--der erste Datensatz muss auf true umschalten
INSERT INTO tb_possible_manufacturer_name(tb_manufacturer_tag,ps_name,preferred_name)
VALUES(1,'Hewlett Packard',false);--'HP' bleibt true
INSERT INTO tb_possible_manufacturer_name(tb_manufacturer_tag,ps_name,preferred_name)
VALUES(1,'Hewlett-Packard',true);--der erste Datensatz ('HP') muss auf false umschalten
UPDATE tb_possible_manufacturer_name SET preferred_name=false WHERE ps_name='Hewlett-Packard';
--Änderung darf nicht akzepiert werden, weil sonst keiner auf true wäre
UPDATE tb_possible_manufacturer_name SET preferred_name=true WHERE ps_name='HP';

Irgendwie habe ich den Eindruck, dass die Trigger machen was sie wollen…
PostgreSQL 8.2.4 auf Windows XP Pro
BTW: Gibt’s irgendwas, um PostgreSQL- Funktionen (unter Windows) zu Debuggen?
Danke schonmal im Voraus

Was spricht dagegen, in der Master-Tabelle die ID des Detail-Datensatzes zu speichern, der grad TRUE ist?

Irgendwie habe ich den Eindruck, dass die Trigger machen was sie wollen...

Es kommt auch nicht gut, in Update-Triggern wieder ein Update der selben Tabelle zu machen. ch hab mir das jetzt nicht so dolle angeschaut, aber vermutlich kann man sich da recht flink ins Bein ballern.

BTW: Gibt's irgendwas, um PostgreSQL- Funktionen (unter Windows) zu Debuggen?
[/QUOTE]

Naja, man kann mit RAISE sich Meldungen zuwerfen lassen...

Andreas

Da spricht genau nichts dagegen. Manchmal sieht man vor lauter Bits die Bytes nicht :slight_smile: .
Danke für den Tip.

Das war mir noch nichtmal aufgefallen… Wie gesagt: manchmal sieht man vor lauter Bits…

Das mache ich ja schon, aber irgendwas zum durchsteppen wär’ halt praktisch…

Danke nochmal, Tschau

Dunkel in Erinnerung: da gibt es was von EDB, kommerziell. Und es wird wohl an einer offiziellen Schnittstelle daran gebastelt.

Andreas