# Oracle Trigger und Jobs?



## flo_e (10. August 2006)

Guten Morgen, Kollegen!

Ich hänge bei folgender Aufgabe:
Nach Eintrag in eine Spalte einer Tabelle wird ein Trigger ausgelöst, der alle Werte dieser Spalte kumuliert und je nach Ergebins ( <>0) eine Emai verschickt. Das klappt auch wunderbar, nur passiert es jedoch ab und zu, dass zwei Einträge kurz hintereinander erfolgen(ca 10 sec) und somit eine Email verschickt wird, obwohl der Wert schon wieder Vergangenheit ist (=> großes Geschrei:"der Rechner kann nicht rechnen"!)
Folgendes habe schon versucht:
gleich nach diesem Eintrag ein
1)
dbms_lock.sleep(20), anschliessend Wert neu berechnet: nice try, ändert nat. nix, ausser das alles 20 sec später passiert... :-(
2)
Als nächstes habe ich versucht, durch den Trigger eine Prozedur aufzurufen, die dann einen Job erstellt, der ca. 30 sec. später nochmal die Werte der Spalte zusammen addiert und dann je nach Ergebnis eine Email versendet. (TRIGGER->PROZEDUR->JOB)
Die Prozedur selbst funktioniert bei Aufruf über eine shell (exec...) wunderbar, mein Job wird erstellt, 30 sec später ausgeführt und löscht sich dann auch brav selber.
Versuche ich jedoch, die Prozedur über eine Trigger aufzurufen, erhalte ich folgenden Fehler:
===schnipp===
ORA-04092: Trigger darf kein ausfhren
ORA-06512: in "SYS.DBMS_ISCHED", Zeile 99
ORA-06512: in "SYS.DBMS_SCHEDULER", Zeile 262
ORA-06512: in "S1.SP_JOB_ORDER", Zeile 30
ORA-06512: in "S1.SP_CHECK_ORDER", Zeile 47
ORA-06512: in "T1.TR_AFTER_INS_ORDER", Zeile 3
ORA-04088: Fehler bei der Ausfhrung von Trigger 'T1.TR_AFTER_INS_ORDER'
===schnapp===
Überprüft habe ich auch alle Berechtigungen.

Wie komme ich hier zu einer brauchbaren Lösung? Gibt es vielleicht eine völlig andere Idee für die Aufgabe einer verzögerten Ausführung?

Version 10gR2
OS: W2k Server

viele Grüße
f*


----------



## ishino (11. August 2006)

Ohne Quellcode kann man nur allgemein sagen, dass Du in Triggern kein COMMIT oder ROLLBACK machen kannst. Es sei denn, Du verwendest "autonomous transactions". Der Trigger wird *waehrend* einer Transaktion ausgefuehrt (der, die den Trigger ausgeloest hat). Ein COMMIT wuerde die aber beenden, ebenso ein ROLLBACK und das wollen wir ja nicht.

*$ORACLE_HOME/rdbms/admin/dbmsjob.sql*


```
rem $Header: dbmsjob.sql 24-may-2001.15:08:07 gviswana Exp Rem      DBMS_JOB and DBMS_IJOB are the only interface for manipulating jobs.
Rem      Queries against the catalog should be used for examining jobs.
Rem      The catalog view dba_jobs and dba_jobs_running are in catjobq.sql.
Rem      Out of all these routines, only dbms_job.run and dbms_ijob.run have
Rem        implicit commits.
```

Wenn Dein Trigger eine von beiden aufruft, hast Du genau das Problem. Man kann das mit Hilfe von 'autonomous transactions' umgehen, allerdings sehe ich dafuer keinen Grund. Wenn Du Dir beispielsweise einen timestamp in eine Tabelle schreibst (innerhalb des Triggers), kannst Du ein Intervallsenden realisieren. Allerdings frage ich mich, wo eigentlich das Problem liegt? Wenn der Trigger ausgeloest wird, dann sollen die Leute halt eine Email bekommen...dazu ist er doch eigentlich da, oder nich? ;-)


----------



## z-coupe (11. August 2006)

ishino hat gesagt.:
			
		

> Allerdings frage ich mich, wo eigentlich das Problem liegt? Wenn der Trigger ausgeloest wird, dann sollen die Leute halt eine Email bekommen...dazu ist er doch eigentlich da, oder nich? ;-)


Genaus das frage ich mich auch. Was soll denn der Job bewirken der 30 Sekunden später ausgeführt wird? Wenn die einen Änderungn nach 35 Sekunden hast ist die E-Mail genau so veraltet wie beim Trigger. Lass es doch bei der Trigger-Lösung. Wenn sich die Daten so häufig verändern wirst du das Problem immer haben.

Ach ja neben dem Commit und Rollback darfst du auch kein Update auf die gleiche Tabelle in einem Update- Trigger machen. Aber wie mein Vorredner schon sagte ohne Quellcode ist nicht viel zu machen


----------

