sql >> Databasteknik >  >> RDS >> PostgreSQL

postgres. plpgsql stackdjupet har överskridits

Ok, om du verkligen vill ha triggern vid uppdatering, vad du kan göra det, ställ in den här triggern som kolumnspecifik, så att den inte aktiveras vid en uppdatering till all_books , vilket orsakar din rekursion. Något sånt här -

create trigger total2
after update of copy_id
on totalbooks
for each row
execute procedure total1();

Naturligtvis kan du ändra vilka kolumner som utlöser funktionen, jag valde bara copy_id för det är vad du räknar.

DOCK

Om du uppdaterar med en count() resultat kan du bara sätta triggern på INSERT och DELETE åtgärder. På så sätt aktiveras utlösaren när räkningen ändras, men den utlöses inte själv av uppdateringen. // EDIT:Eftersom din sum är bara ett antal av alla poster i copies , kommer den bara att ändras när en post infogas eller uppdateras, så att köra den här utlösaren vid uppdatering skulle inte vara meningsfullt ändå.

EDIT:Jag tänkte att det skulle vara användbart att lägga till en länk till SKAPA TRIGGER-dokumentation . Se avsnittet märkt "händelse", eftersom det här beskriver hur man anger kolumner i händelsen.

REDIGERA FÖR NY INFORMATION:

Med tanke på vad det låter som att du behöver åstadkomma, tror jag att du måste tänka om din datadesign, jag föreslår att du använder en förälder-barn-relation (varje gång du cachelagrar delad data på många rader i en tabell eftersom de delar något gemensamt, att är ett tecken på att du kan behöva ett föräldrabord istället).

Ha en books tabell där varje rad är information om en bok (titel, författare, etc), och sedan har en copies tabell där varje rad innehåller information om ett exemplar av en bok (serienummer, senast utcheckad, etc).

På så sätt är det så enkelt att få antalet kopior som SELECT COUNT(*) FROM copies WHERE book_id=[some book id] .

Om du verkligen vill cachelagra räkningen någonstans, gör det i books tabell.

Skapa en INSERT OR UPDATE trigger på copies som gör UPDATE books SET copy_count=(SELECT COUNT(*) FROM copies WHERE book_id=NEW.book_id) WHERE id=NEW.book_id .

Skapa sedan en DELETE trigger på kopior som gör UPDATE books SET copy_count=(SELECT COUNT(*) FROM copies WHERE book_id=OLD.book_id) WHERE id=OLD.book_id

Anledningen till två utlösare är att NEW variabel är endast tillgänglig i INSERT eller UPDATE triggers och OLD är endast tillgänglig i DELETE triggers. Du kan göra allt som en utlösare, men det kräver mer kod än jag ville lägga här.

Se till att alla dina utlösare är AFTER utlöser, annars kommer en nyinfogad/borttagen rad inte att beaktas i räkningen.



  1. FEL:inmatningsparametrar efter en med ett standardvärde måste också ha standardvärden i Postgres

  2. dynamisk fråga i Oracle-proceduren med hjälp av markören

  3. ORA-04084:kan inte ändra NYA värden för denna triggertyp

  4. Anslutningspoolen för databasen '/data/data/msv_database.db' har inte kunnat bevilja en anslutning. Anslutningar:0 aktiva, 1 ledig, 0 tillgängliga