2014-10-09 9 views
5

Postgres Mit 9,3:Postgres Regeln Verhindern CTE Abfragen

ich versucht bin, um automatisch eine Tabelle zu füllen, wenn ein Einsatz auf einer anderen Tabelle ausgeführt wird. Das scheint eine gute Anwendung für Regeln zu sein, aber nachdem ich die Regel der ersten Tabelle hinzugefügt habe, kann ich mit dem beschreibbaren CTE keine Inserts in die zweite Tabelle mehr durchführen. Hier ein Beispiel:

CREATE TABLE foo (
    id INT PRIMARY KEY 
); 

CREATE TABLE bar (
    id INT PRIMARY KEY REFERENCES foo 
); 

CREATE RULE insertFoo AS ON INSERT TO foo DO INSERT INTO bar VALUES (NEW.id); 

WITH a AS (SELECT * FROM (VALUES (1), (2)) b) 
INSERT INTO foo SELECT * FROM a 

Wenn dies ausgeführt wird, erhalte ich den Fehler

"ERROR: WITH cannot be used in a query that is rewritten by rules into multiple queries".

ich für diesen Fehler Zeichenfolge gesucht habe, aber ich bin nur in der Lage Links zum Quellcode zu finden. Ich weiß, dass ich das oben genannte mithilfe von Triggern auf Zeilenebene durchführen kann, aber es scheint, als ob ich dies auf Anweisungsebene tun könnte. Warum kann ich nicht den beschreibbaren CTE verwenden, wenn Abfragen wie folgt (in diesem Fall) werden leicht neu geschrieben als:

INSERT INTO foo SELECT * FROM (VALUES (1), (2)) a 

Hat jemand eine andere Art und Weise weiß, dass würde erreichen, was ich versuche, andere zu tun, als 1) Regeln verwenden, die die Verwendung von "mit" -Abfragen verhindern oder 2) Trigger auf Zeilenebene verwenden? Danke,

+3

Warum Sie einen Trigger nicht verwenden? –

+0

Meine Datenbank Erfahrung ist nur etwa 5 Monate, also wenn ich auf ein Problem stoße, dass ich keine Lösung finde, die ich wirklich mag, denke ich, dass ich die Experten fragen sollte, damit ich über die verschiedenen Optionen lernen kann. Für etwas so einfaches schien eine Regel aus Performancegründen der Weg zu sein, aber ich mag die Einschränkung nicht, die beschreibbare CTE in Abfragen nicht verwenden zu können. –

+0

Ich sollte hinzufügen, dass ich plane, Trigger auf Zeilenebene als die Lösung der Wahl zu verwenden, es sei denn, jemand bietet eine bessere Alternative hier bei SO. –

Antwort

3

TL; DR: Verwenden Sie Trigger, keine Regeln.

Im Allgemeinen bevorzugen Trigger über Regeln, es sei denn Regeln sind absolut notwendig. (Was sie in der Praxis nie sind.)

Die Verwendung von Regeln führt zu einer Vielzahl von Problemen, die Ihr Leben auf der Straße unnötig erschweren werden. Du bist hier in einen geraten. Ein anderes (bedeutendes) ist zum Beispiel, dass die Anzahl der betroffenen Zeilen derjenigen der allerletzten Abfrage entspricht - wenn Sie sich auf FOUND verlassen und Ihre Abfrage fälschlicherweise meldet, dass keine Zeilen von einer Abfrage betroffen sind, Sie werden schmerzhafte Käfer bekommen.

Darüber hinaus gibt es gelegentliche Rede Postgres von ironischen Regeln geradezu:

http://postgresql.nabble.com/Deprecating-RULES-td5727689.html

Verwandte Themen