Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Oracle Procedure Aufruf im Trigger

Frage Entwicklung Datenbanken

Mitglied: BadFsaadKl

BadFsaadKl (Level 1) - Jetzt verbinden

25.06.2014, aktualisiert 26.06.2014, 1948 Aufrufe, 3 Kommentare

Moin zusammen,

ich habe ein kleines Problem, einen Datenbank Trigger zum laufen zu bekommen, und hoffe Ihr könnt mir hier helfen.
Ich habe eine Procedure geschrieben, welche ein Update auf eine Tabelle macht, und 2 Parameter benötigt.
Anbei mal die Procedure
01.
create or replace  
02.
procedure add_flugstunden 
03.
04.
  p_per_nr in osq01_pilot.per_nr%TYPE, 
05.
  p_bez in osq01_flug.f_bez%TYPE 
06.
07.
  is 
08.
  BEGIN 
09.
   	declare 
10.
    	cursor cur_get_data 
11.
    	is 
12.
    		select 
13.
      			pil.p_std, 
14.
      			flg.zeit 
15.
    		from 
16.
      		osq01_pilot pil, 
17.
      		osq01_flug flg, 
18.
      		osq01_abflug aflg 
19.
    		where 
20.
      			aflg.f_bez = flg.f_bez and 
21.
      			aflg.per_nr = pil.per_nr and 
22.
      			aflg.f_bez = p_bez 
23.
24.
    	 
25.
    	v_p_std   osq01_pilot.p_std%TYPE; 
26.
    	v_zeit    osq01_flug.zeit%TYPE; 
27.
    	 
28.
  		begin 
29.
    		open cur_get_data; 
30.
          fetch cur_get_data into v_p_std, v_zeit; 
31.
    			update osq01_pilot 
32.
    			set p_std = v_p_std + v_zeit 
33.
    			where 
34.
      			per_nr = p_per_nr; 
35.
    		close cur_get_data; 
36.
    	end; 
37.
  END add_flugstunden;
Nun brauche ich einen Trigger, der jedesmal wenn auf eine bestimmte Tabelle ein Update oder Insert gemacht wird, der Trigger ausgelöst wird.
Aktuell sieht mein Trigger wie folgt aus:
01.
create or replace trigger tr_add_flugstunden 
02.
after insert or update on osq01_abflug 
03.
for each row 
04.
begin 
05.
  add_flugstunden(:new.per_nr, :new.f_bez); 
06.
end tr_add_flugstunden; 
07.
/
Der Trigger wurde soweit auch erstellt.
Jedoch wenn ich einen Insert auf die Tabelle osq01_abflug mache, erhalte ich folgende Fehlermeldung:
01.
Fehlerbericht: 
02.
SQL-Fehler: ORA-04091: table SGD.OSQ01_ABFLUG is mutating, trigger/function may not see it 
03.
ORA-06512: at "SGD.ADD_FLUGSTUNDEN", line 11 
04.
ORA-06512: at "SGD.ADD_FLUGSTUNDEN", line 28 
05.
ORA-06512: at "SGD.TR_ADD_FLUGSTUNDEN", line 2 
06.
ORA-04088: error during execution of trigger 'SGD.TR_ADD_FLUGSTUNDEN' 
07.
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it" 
08.
*Cause:    A trigger (or a user defined plsql function that is referenced in 
09.
           this statement) attempted to look at (or modify) a table that was 
10.
           in the middle of being modified by the statement which fired it. 
11.
*Action:   Rewrite the trigger (or function) so it does not read that table.
Anbei auch mein Insert Befehl:
01.
INSERT INTO OSQ01_ABFLUG( F_BEZ, AB_DATUM, PER_NR, HERST, TYP, SER_NR, AB_ZEIT) 
02.
VALUES ('LH-341','14.11.06','10010001','Boeing','B737','ba23-0012','10,23')
Hat jemand eine Idee wo hier mein Fehler liegt und kann mir helfen ?

Danke

Gruß
BadFsaadKl
Mitglied: Biber
LÖSUNG 25.06.2014, aktualisiert 26.06.2014
Moin BadFsaaKl,

soweit ich deine Tabellenstruktur verstehe, kannst du doch wirklich auf ein Lesen der "Abflug"-Tabelle verzichten, wie in der Fehlermeldung nahegelegt.

Deine procedure sollte auch so funktionieren:
01.
create or replace  
02.
procedure add_flugstunden 
03.
04.
  p_per_nr in osq01_pilot.per_nr%TYPE, 
05.
  p_bez in osq01_flug.f_bez%TYPE 
06.
07.
  is 
08.
  BEGIN 
09.
   	declare 
10.
    	cursor cur_get_data 
11.
    	is 
12.
    		select 
13.
      			pil.p_std, 
14.
      			flg.zeit 
15.
    		from 
16.
      		osq01_pilot pil, 
17.
      		osq01_flug flg 
18.
    		where 
19.
      	                pil.per_nr = p_per_nr 
20.
      			flg.f_bez = p_bez 
21.
22.
    	 
23.
    	v_p_std   osq01_pilot.p_std%TYPE; 
24.
    	v_zeit    osq01_flug.zeit%TYPE; 
25.
    	 
26.
  		begin 
27.
    		open cur_get_data; 
28.
          fetch cur_get_data into v_p_std, v_zeit; 
29.
    			update osq01_pilot 
30.
    			set p_std = v_p_std + v_zeit 
31.
    			where 
32.
      			per_nr = p_per_nr; 
33.
    		close cur_get_data; 
34.
    	end; 
35.
  END add_flugstunden;
...denn das bisher "joinende" Kriterium "aflg.f_bez = flg.f_bez and aflg.per_nr = pil.per_nr and aflg.f_bez = p_bez" läuft doch -ins Deutsche übersetzt- darauf hinaus, dass du jeweils genau einen Satz aus drei Tabellen liest und als Kreuzprodukt (1row*1*row*1row) dann eben auch genau einen Satz im Resultset erhältst.
Das geht auch als Kreuzprodukt aus zwei Tabellen.

Ich verstehe nicht, warum du einen Cursor verwendest... Trigger beziehen sich doch üblicherweise auf EINEN Datensatz, der INSERTed/UPDATEd oder DELETEd wird - so wie bei dir.
Trigger mit dem Scope "TABLE" gibt es auch - aber den brauchst du doch nicht in deinem Fall.

Ein Update oder Insert in der Abflug-Tabelle führt doch immer nur zu genau einem Folge-Update-Datensatz in der "Pilotstunden"-Tabelle - oder lese ich das falsch?

Grüße
Biber
Bitte warten ..
Mitglied: BadFsaadKl
26.06.2014 um 20:25 Uhr
Biber,

du bist mein Held... :D
Ich hab mal wieder nur zu kompliziert gedacht.

Trigger funktioniert nun einwandfrei...

Danke dir.
Bitte warten ..
Mitglied: Biber
26.06.2014, aktualisiert um 21:26 Uhr
Moin BadFsaadKl,


na ja, sagen wir so - der Trigger bringt wohl keine Fehlermeldung mehr.

Allerdings würde ich noch mal in Ruhe darüber meditieren
a) ob du überhaupt einen Cursor brauchst, den du dann vollständig vom ersten bis zum ...ähmmm... ersten Satz durchfetchst - dafür würde auch ein einfaches direktes "UPDATE pilotentabelle" reichen IMHO.
b) und vor allem, ob denn wirklich bei jedem UPDATE in der abflug-Tabelle nochmal die Stunden in der Piloten-Tabellen addiert werden sollen.

Bei einem INSERT ja, durchaus.
Bei einem noch zu ergänzenden DELETE-Trigger auf der Abflug-Tabellen könnten ebenso blind wieder Stunden in der Pilotentabelle rausgerechnet werden.

Bei einem Update der Abflug-Tabelle, z.B weil jemand einen Tippfehler im Feld "Typ" von "Boeing 773" zu "Boeing 737" korrigiert - da kann es doch noch nicht sein, dass deswegen nochmals die Flugzeitstunden einem Piloten gutgeschieben werden.

Weil - die verdienen ohnehin schon genug.

Ich würde - schon zu Übungszwecken - nochmal
  • einen UPDATE-Trigger schreiben (der nur bei einer Änderung der Felder "per_nr" und/oder "f_bez" feuert - denn in diesen Fällen müssen die bereits gebuchten Pilotenstunden reduziert werden und einem anderen Piloten gutgeschrieben werden)
  • und den fehlenden DELETE-Trigger musst du ohnehin schreiben, es sei denn, ein Löschen eines Datensatzes der Abflug-Tabelle ist absolut ausgeschlossen.

Grüße
Biber
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Datenbanken
Microsoft SQL Server Feld mit Trigger aktualisieren (3)

Frage von ursus57 zum Thema Datenbanken ...

Backup
Backup von laufender Oracle-Datenbank - VSS writer (4)

Frage von brain2011 zum Thema Backup ...

Windows Server
gelöst Oracle ODBC Treiber in Windows 2008 R2 (3)

Frage von kschi12 zum Thema Windows Server ...

Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...