Silizium185 Geschrieben 7. September 2012 Teilen Geschrieben 7. September 2012 Hallo, ich habe folgendes Problem. Ich habe eine Prozedur die einen Integerwert übergeben bekommt. Diese Prozedur soll den Integerwert über eine Insert Into anweisung in eine Tabelle schreiben. Jedoch habe ich einen Trigger der bevor die Insert Anweisung ausgeführt wird, ausgelöst werden soll (before Insert). Der Trigger soll gucken, ob der Integerwert den die Prozedur übergeben bekommen hat, bereits vorhanden ist. Mein Problem ist, wie kann ich dem Trigger den Integer aus der Prozedur übergeben. Kann mir da jemand helfen?? Ich verwende Sybase Anywhere als Datenbank Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 7. September 2012 Teilen Geschrieben 7. September 2012 für ein Select in der Prozedur / Trigger aus und prüfe ob das Result leer ist (sofern der Wert PK ist, wenn nicht, musst Du halt eben passend das Result verarbeiten) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Silizium185 Geschrieben 7. September 2012 Autor Teilen Geschrieben 7. September 2012 nee das funzt leider nicht. Er findet keine Ergebnismenge Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Hi, leg einen Unique Constraint auf die Spalte und die DB erledigt das für dich. Das in einem Trigger zu erledigen ist ein klarer Bug im Anwendungsdesign und kann doppelten Einträgen führen. Den Fehler, den die DB bei einem doppelten Wert erzeugt kannst Du dann in der Prozedur abfangen. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Das in einem Trigger zu erledigen ist ein klarer Bug im Anwendungsdesign und kann doppelten Einträgen führen. Das geht nur, wenn der Datensatz eindeutig ist und ist dann auch die erste Wahl, wenn aber eine Teilmenge betrachtet werden soll, dann bietet sich ein Trigger an. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Das geht nur, wenn der Datensatz eindeutig ist und ist dann auch die erste Wahl, wenn aber eine Teilmenge betrachtet werden soll, dann bietet sich ein Trigger an. Vgl: Der Trigger soll gucken, ob der Integerwert den die Prozedur übergeben bekommen hat, bereits vorhanden ist. Wo ist da eine Teilmenge? Und nachsehen, ob eine Zahl schon vorhanden ist, hört sich ganz verdächtig nach "Eindeutigkeit" an. Des weiteren sieht ein Trigger keine offenen Transaktionen und kann daher nicht prüfen, ob die Zahl wirklich nicht schon eingefügt wurde, aber der Commit noch nicht durch ist. Verwendet man einen Dirty read (ist per Definition aber schon ein Bug in jeder DB Anwendung und daher auch nicht in allen Datenbanken verfügbar), dann kann man nicht sicher sein, ob die Zahl vielleicht nicht per Rollback wieder verschwindet und man aber einen schon vorhandenen Wert ermittelt hat, der jetzt aber nicht mehr da ist. Die einzigen, sauberen (=fehlerfreien) Möglichkeiten sind: * Serialisieren des Zugriffs, sprich exclusives sperren der Tabelle, dann in der Prozedur per SQL nachsehen, ob der Wert schon vorhanden ist. Warum hier überhaupt ein Trigger verwendet werden soll ist mir eh nicht klar, ebensowenig, ob man den Zugriff serialisieren möchte. Vermutlich eher nicht * Verwenden eines Unique Constraints und die DB ihren Job machen lassen. Andere "Methoden" führen, auch bei Teilmengen, dazu, dass der Datenstand bei bestimmten Konstellationen fachlich inkonsistent werden kann und vermutlich auch wird. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Wo ist da eine Teilmenge? Das stimmt, ich hatte das anders gelesen. Die einzigen, sauberen (=fehlerfreien) Möglichkeiten sind: * Serialisieren des Zugriffs, sprich exclusives sperren der Tabelle, dann in der Prozedur per SQL nachsehen, ob der Wert schon vorhanden ist. Warum hier überhaupt ein Trigger verwendet werden soll ist mir eh nicht klar, ebensowenig, ob man den Zugriff serialisieren möchte. Vermutlich eher nicht Wenn es ein Trigger sein sollte, dann würde ich eher eine Prozedure nehmen und nicht per Trigger prüfen, sondern die Prozedure prüft ob der Wert vorhanden, wenn ja wird abgebrochen, wenn nein eingefügt. Bei Postgres sind Prozedure automatisch atomar und wenn man sie nochmals in eine Transaktion packt, dann laufen sie im Kontext der Transaktion * Verwenden eines Unique Constraints und die DB ihren Job machen lassen. Das ist definitiv die beste Lösung Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Bei Postgres sind Prozedure automatisch atomar und wenn man sie nochmals in eine Transaktion packt, dann laufen sie im Kontext der Transaktion Mir ging es hier insbesondere um Multiuserzugriffe. Sprich Session A fügt die Zahl 100 ein, hat aber noch nicht comittet, Session B prüft, ob die Zahl 100 schon vorhanden ist und bekommt eine leere Menge zurück, fügt sie also auch ein. Nachdem beide Sessions comittet haben steht zweimal die Zahl 100 drinnen. Daher der "Lösungsansatz" mit dem exklusiven Sperren der Tabelle, dann kann nur eine Session in der Tabelle ändern, die anderen müssen warten. Ist natürlich nicht praktikabel aber zumindest eine (rein) theoretische Lösung. Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Daher der "Lösungsansatz" mit dem exklusiven Sperren der Tabelle, dann kann nur eine Session in der Tabelle ändern, die anderen müssen warten. Ist natürlich nicht praktikabel aber zumindest eine (rein) theoretische Lösung. Das stimmt, ich meine mich z.B. bei Postgres daran erinnern zu können, dass man aus einer Prozedure auch mit anderen aktuell laufenden Sessions Daten austauschen kann, also so etwas wie ein Semaphor. Wenn man das nimmt, dann könnte man eben prüfen, ob eine andere Session kollidieren würde. Aber das nur so am Rande Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 12. September 2012 Teilen Geschrieben 12. September 2012 Das stimmt, ich meine mich z.B. bei Postgres daran erinnern zu können, dass man aus einer Prozedure auch mit anderen aktuell laufenden Sessions Daten austauschen kann, also so etwas wie ein Semaphor. Wenn man das nimmt, dann könnte man eben prüfen, ob eine andere Session kollidieren würde. Aber das nur so am Rande Vermutlich so etwas ähnliches wie DBMS_PIPE in Oracle. Aber da ist mir der Unique Constraint doch lieber Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.