CREATE TABLE auto
(
id serial NOT NULL,
farbe character varying,
CONSTRAINT pk_id PRIMARY KEY (id )
)
WITH (
OIDS=FALSE
);
mit der folgenden Regel:
CREATE OR REPLACE RULE rule_auto_i AS
ON INSERT TO auto
WHERE (( SELECT auto.id
FROM auto
WHERE auto.farbe::text = new.farbe::text)) IS NOT NULL DO INSTEAD NOTHING;
Wenn ich nun ein INSERT mit RETURNING mache:
INSERT INTO auto(farbe) VALUES ('rot') RETURNING id;
bekomme ich folgende Fehlermeldung:
ERROR: cannot perform INSERT RETURNING on relation "auto"
HINT: You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.
********** Fehler **********
ERROR: cannot perform INSERT RETURNING on relation "auto"
SQL Status:0A000
Hinweis:You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.
Ist das evtl. ein Bug?
Das liegt anscheinend an der Regel.
Kann ich Postgresql, obwohl ich eine Regel definiert habe, irgendwie überreden mir doch den PRIMARY KEY mit RETURNING zurückzugeben?
Wieso sollte das ein Bug sein?
Die Fehlermeldung sagt doch ziemlich deutlich was fehlt: You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause
Deine Regel hat weder ein “RETURNING” dabei noch ist sie “unconditional”. Also ein Regel grundsätzlich - ohne Bedingung - ausgeführt wird.
Offensichtlich willst Du verhindern, dass zwei Autos mit der gleichen Farbe eingefügt werden. Da ist ein UNIQUE index auf die Spalte farbe sicherlich die bessere (und performantere) Lösung.
Ich benutze ein vorgefertigtes Schema (biosql.org). Da sind leider lauter solche Regel definiert. Dein Tip mit dem UNIQUE index ist bestimmt der richtige Weg.
Ich würde nur gene erst mal nichts am Schema verändern, bzw. nur die Regel etwas anpassen. Ich bin nicht im Stande gewesen die Regel so anzupassen, das sie mit RETURNING funktioniert.
Könnte man das über eine zusätzliche unconditional Regel ein RETURNING hinbekommen. Wenn ja, wie müsste die dann aussehen?
Unconditional heisst “ohne Bedingung”. Du musst also die WHERE Bedingung rausnehmen, aber das würde die Regel ad-absurdum führen.
So wie das derzeit gelöst ist, wirst Du das mit dem RETURNING nicht hinkriegen. Ersetze die sinnlose Regel durch ein anständigen Constraint und Du hast keine Probleme.
Vielleicht schreibst Du ja den Autoren dieses Schema eine Email und erklärst denen, dass genau für solche Anforderungen unique constraints bzw. Indizes erfunden wurden. Die Mailingliste die auf der Homepage verlinkt ist, ist vermutlich ein guter Anfang dafür (BioSQL-l Info Page bzw. biosql-l@lists.open-bio.org)
Die andere Alternative wäre noch ein Trigger.
Rules werden zur Compile-Zeit der Anfrage zusammengestellt, daher müssen alle Daten der WHERE Bedingung aus der Anfrage (bzw. den Daten der Anfrage) vorliegen. Einfach mal so noch weitere Daten auslesen … schlecht.