2014-10-09 15 views
5

Korzystanie z PostgreSQL 9.3:Postgres Zasady Zapobieganie CTE Pytania

I m próbuje automatycznie wypełnić tabelę, gdy wkładka jest wykonywana na innym stole. Wydaje się, że jest to użyteczne dla reguł, ale po dodaniu reguły do ​​pierwszej tabeli nie jestem już w stanie wprowadzać wstawek do drugiej tabeli przy użyciu zapisywalnego CTE. Oto przykład:

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 

Gdy ta jest prowadzona, pojawia się błąd

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

Szukałem dla tego łańcucha błędów, ale jestem tylko w stanie znaleźć linki do kodu źródłowego. Wiem, że mogę wykonać powyższe używając wyzwalaczy na poziomie wiersza zamiast, ale wydaje się, że powinienem być w stanie to zrobić na poziomie instrukcji. Dlaczego nie mogę używać zapisu CTE, kiedy pytania takie jak to może (w tym przypadku) być łatwo ponownie zapisać jako:

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

Czy ktoś zna inny sposób, który będzie osiągnąć to, co ja próbuje zrobić inny niż 1) używając reguł, które uniemożliwiają użycie zapytań "z" lub 2) używając wyzwalaczy na poziomie wiersza? Dzięki,

+3

Dlaczego nie chcesz używać spust? –

+0

Moje doświadczenie z bazą danych wynosi tylko około 5 miesięcy, więc w każdej chwili napotkam problem, że nie mogę znaleźć rozwiązania, które bardzo mi się podoba, sądzę, że powinienem zapytać ekspertów, aby dowiedzieć się o różnych opcjach. W przypadku czegoś tak prostego, zasada wydawała się być sposobem na spełnienie wymagań wydajności, ale nie podoba mi się ograniczenie bycia niezdolnym do używania zapisywalnego CTE w zapytaniach. –

+0

Należy dodać, że planuję użyć wyzwalaczy na poziomie wiersza jako rozwiązania z wyboru, chyba że ktoś dostarczy lepszą alternatywę tutaj w SO. –

Odpowiedz

3

TL; DR: użyj wyzwalaczy, a nie reguł.

Ogólnie rzecz biorąc, preferuj wyzwalacze ponad reguły, chyba że reguły są absolutnie konieczne. (Które w praktyce nigdy nie są.)

Stosowanie reguł wprowadza mnóstwo problemów, które niepotrzebnie komplikują życie na drodze. Wpadłeś na jednego tutaj. Innym (głównym) jest na przykład to, że liczba dotkniętych wierszy będzie odpowiadać liczbie ostatniego zapytania - jeśli polegasz na FOUND gdzieś i twoje zapytanie nieprawidłowo zgłasza, że ​​zapytanie nie miało wpływu na żadne wiersze, będziesz mieć bolesne błędy.

Ponadto istnieje sporadyczne rozmowy o deprecjację Postgresa rządzi wprost:

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