Hi,
so richtig verstehe ich den Vorteil der Umsetzung einer Triggerfunktion nicht. Mein Problem, dass ich die Values alle benennen möchte, sehe ich nicht gelöst.
So verstehe ich das und ich lasse mich gerne korrigieren.
1. Erstellen einer Triggerfunktion, die bei Aufruf eines Updates auf der Vatertabelle aufgerufen wird
2. In dieser Triggerfunktion wird anhand das Partitionsattributes selektiert (über IF ELSE Anweisungen), dass die korrekte Partition ausgewählt wird für das Update
3. die Update Anweisung dafür ist aber doch wieder ein Update [tabellenname] SET .... WHERE ... oder nicht?
mfg
Marcus
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
das koennte er sich bei der triggerfunktion ja sparen
@dingens ..
es geht darum, dass du solche sachen machen kannst
schau dir einfach mal in der doku an wie man row-level trigger schreibt und was man damit alles treiben kann ... mit ein wenig fantasie kommst du dann schon auf die richtigen ideenCode:CREATE OR REPLACE FUNCTION dispatch_partition() RETURNS trigger AS $BODY$ BEGIN -- IF TG_OP = 'UPDATE' AND TG_WHEN = 'BEFORE' THEN IF NEW.date = ... THEN -- redirect .. hier koenntest auch loeschen oder update??? woanders hin etc pp INSERT INTO .... VALUES (NEW.*); -- skip operation RETURN NULL; END IF; -- continue RETURN NEW; END IF; RETURN NULL; -- skip operation END $BODY$ LANGUAGE 'plpgsql' VOLATILE;
mir ist nicht ganz klar, wieso du bei einem update das partitionsattribut auswertest - und dann ein update ausfuehren musst - wenn sich die partition aendert, dann sollte das maximal in ein delete in er alte partition fuehren und in ein insert in der neuen ... dafuer brauchst du aber die felder nicht -> NEW.*
hey,
sorry hatte momentan andere Aufgaben zu erledigen und konnte mich nicht um das Update kümmern. Nun hat sich aber ein anderes Problem aufgezeigt.
@symbiont
Ich habe eigentlich 2 Update Rules pro Partition. Einmal, wenn sich durch ein Update die Partition ändert, so wird aus der alten gelöscht und in die neue eingefügt.
Zum anderen, wenn sich durch ein Update die Partition nicht ändert, so soll dann nur in der betreffenden Partition geupdatet werden. Ob dies so berhaupt möglich ist, bezweifle ich langsam. Ich kann ja nicht die WHERE Klausel des normalen Updates in die Update Rule mitnehmen bzw. übergeben. So weis ich ja nie, für welche Datensätze das Update nun gilt.
Habe ich hier einen Denkfehler? Gibt es eine Alternative, oder ist die 2. Update Rule völlig sinnlos?
mfg
Marcus
natuerlich ist das moeglich
um mal die idee anzudeuten..Code:IF TG_OP = 'UPDATE' THEN ... IF TG_WHEN = 'BEFORE' THEN partition_changed = .... IF partition_changed THEN -- aus alter partition loeschen DELETE FROM .. -- in neue partition einfuegen INSERT INTO ... NEW.* -- update skippen .. indem man im BEFORE trigger NULL zurueckgibt RETURN NULL; ELSE -- update fortsetzen RETURN NEW; END END END
Dank dir erstmal!
Bin noch nicht dazu gekommen, da sich weitere Probleme ergeben haben und die Update Rules bzw. Trigger ja später immernoch implementiert werden können.
mfg
Marcus
Also, ich bekomme es nicht hin, weder mit Rules noch mit Triggern Partitionierung korrekt abzubilden. Der Insert ist klar, aber beim Delete und Update habe ich Probleme. Beim Delete löscht es mir die ganze Partition, da ich die Bedingungen in der Where Klausel nicht an die Rule übergeben kann. Beim Trigger ist es das selbe.
Habt ihr vielleicht ein Beispiel, wie das geht?
mfg
Marcus
Unter:
Hauptseite [PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler]
gibt es sowohl für Trigger wie für Rules jeweils ein komplettes Beispiel.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
Was ist mit den Beispielen aus dem Handbuch?
PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: Rules on INSERT, UPDATE, and DELETE
bei rowlevel trigger brauchst du die bedinung nicht kennen, da der trigger - wie der name sagt - fuer jede betroffene row augerufen wird ..
wenn du also ein anderes statement aufrufst wirst du als bedingung den key der table verwenden ..
Rowlevel Trigger:
Code:CREATE TRIGGER tg_mach_was_anderes_bei_update BEFORE INSERT ON myschema."MY_TABLE" FOR EACH ROW EXECUTE PROCEDURE myschema.funktion_mach_was_anderes_bei_update();Code:CREATE OR REPLACE FUNCTION myschema.funktion_mach_was_anderes_bei_update RETURNS trigger AS $BODY$ BEGIN IF TG_OP = 'UPDATE' AND TG_WHEN = 'BEFORE' THEN -- zum beispiel loeschen .. ich nehme an du hast einen key - der koennte z.B. id heissen .. DELETE FROM ... WHERE id = NEW.id; -- update nicht durchfuehren RETURN NULL; END; RETURN NEW; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE COST 1;
Geändert von symbiont (04.10.2009 um 16:40 Uhr)
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen