Oracle 9 Trigger Problem mit der V$session

Hallo Zusammen,

hab ein kleines Problem unter Oracle 9.02.
Hab einen Trigger der unter Oracle 8 bereits einwandfrei läuft aber unter Oracle 9 kompilierungsfehler bekommt.

Hier erstmal der Trigger

create or replace trigger ro_del_sp
before delete on „SpProCar“
for each row
declare
position number;
laenge number;
differ number;
machine varchar2(100);
machine2 varchar2(100);
lmachine2 number;
username varchar2(100);
program varchar2(200);
reg2 varchar2(100);
begin

if :old.„classid“='SCSCurProCar’then
select s.machine into machine from v$session s where s.audsid = userenv(‚sessionid‘);
select s.osuser into username from v$session s where s.audsid = userenv(‚sessionid‘);
select s.program into program from v$session s where s.audsid = userenv(‚sessionid‘);

position:=instr(machine,’’,1);
laenge:=length(machine);

differ:=laenge-position;

select upper(trim(substr(machine,position+1,differ-1))) into machine2 from dual;
select length(trim(substr(machine,position+1,differ-1))) into lmachine2 from dual;

select nvl(min(regvalue),‚Kein Wert‘) into reg2 from ADMAPPPROFILE where username like ‚%DEFAULT%‘
and upper(substr(regname,1,lmachine2)) = machine2;

insert into ro_sp
(„proCarId“,datum,„chassisNo“,„orderNo“,„classid“,„proId“,lastlogin,machine,osuer,program)
values (:old.„proCarId“,sysdate,:old.„chassisNo“,:old.„orderNo“,:old.„classid“,:old.„proId“,reg2,machine,username,program);

END IF;

end;
/

Das Problem liegt im Zugriff auf die v$session.
Hier bekomme ich immer wieder die Meldungen unter show errors
15/2 PL/SQL: SQL Statement ignored
15/40 PL/SQL: ORA-00942: table or view does not exist
16/2 PL/SQL: SQL Statement ignored
16/40 PL/SQL: ORA-00942: table or view does not exist
17/2 PL/SQL: SQL Statement ignored
17/40 PL/SQL: ORA-00942: table or view does not exist

Eine normale Abfrage auf die v$session geht aber ?

Bin dankbar für jede Hilfe

Mahlzeit,

hab ein kleines Problem unter Oracle 9.02.
Hab einen Trigger der unter Oracle 8 bereits einwandfrei läuft
aber unter Oracle 9 kompilierungsfehler bekommt.

Dein Problem hat nichts mit den unterschiedlichen Versionen zu tun, sondern damit, daß gegrantete Privilegien, die über Rollen erfolgen, in Prozeduren nicht gelten. Siehe dazu: https://metalink.oracle.com/metalink/plsql/f?p=130:1…
(Anmeldung erforderlich).

Lösung: grant select on v$session to ;

Gruß

Sancho

Danke für den Tipp.
mit der v$session geht es zwar nicht weil es ein Synonym ist.
Aber auf die v_$session, die ein View ist, gehts.

Nochmals vielen Dank für den Gedanklichen Fußtritt.

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Manfred,

hab ein kleines Problem unter Oracle 9.02.
Hab einen Trigger der unter Oracle 8 bereits einwandfrei läuft
aber unter Oracle 9 kompilierungsfehler bekommt.

Die Lösung dafür hast du ja schon bekommen. Ich stürze mich wieder einmal auf „Nebensächlichkeiten“.

> create or replace trigger ro\_del\_sp  
> before delete on "SpProCar"  
> for each row  
> declare  
> position number;  
> laenge number;  
> differ number;  
> machine varchar2(100);  
> machine2 varchar2(100);  
> lmachine2 number;  
> username varchar2(100);  
> program varchar2(200);  
> reg2 varchar2(100);

Du deklarierst hier mehrere Variablen für "SELECT INTO"s. Die fixen Typen gehen nur gut, so lange niemand den Typ in den Tabellen ändert (z.B. VARCHAR2(2000) auf CLOB, bei Systemtabellen hast du darauf noch nicht mal Einfluss…). Besser wäre hier

[...]
machine v$session.machine%TYPE
[...]

Zum eigentlichen Trigger (ich habe die Formatierung etwas umgestellt, damit die Tags nicht alles zerschießen):

> begin  
>   
> if :old."classid"='SCSCurProCar'then  
> select s.machine into machine from v$session s   
> where s.audsid = userenv('sessionid');  
> select s.osuser into username from v$session s  
> where s.audsid = userenv('sessionid');  
> select s.program into program from v$session s  
> where s.audsid = userenv('sessionid');

Warum 3 Selects, wo doch einer auch geht?

SELECT machine, osuser, program FROM v$session
 WHERE s.audsid = userenv('sessionid');

Ist jetzt bei der v$session eher keine Tragödie, bei anderen Tabellen aber schlicht eine verdreifachung der Zugriffszeit und du müllst den cursor cache unnötig zu.

> position:=instr(machine,'\',1);  
> laenge:=length(machine);  
>   
> differ:=laenge-position;  
>   
> select upper(trim(substr(machine,position+1,differ-1))) into  
> machine2 from dual;  
> select length(trim(substr(machine,position+1,differ-1))) into  
> lmachine2 from dual;

Grober Fehler: Wofür hier einen SELECT? Du bist in PL/SQL, kannst also einfach auch schreiben:

machine2 := upper(trim(substr(machine,position+1,differ-1)));

Hier ist der Impact noch größer als zuvor. Der DB-Zugriff ist komplett überflüssig, reine Beschäftigungstherapie, auch wenn die DUAL die schnellste Tabelle im System ist. Aufgrund der nötigen Parses kann auch genau sowas zu einem Performance-Killer werden (klingt komisch, ist aber so…).
Eine letzte Anmerkung noch zum nächsten SELECT:

> select nvl(min(regvalue),'Kein Wert') into reg2 from ADMAPPPROFILE  
> where username like '%DEFAULT%'  
> and upper(substr(regname,1,lmachine2)) = machine2;

Ich hoffe das ist eine kleine Tabelle. Das ist nämlich immer und überall ein Full Table Scan. Wenn das eine potentiell große Tabelle wird, dann unbedingt cachen, ich vermute anhand des Statements, dass das Ergebnis hier innerhalb einer Session ohnehin immer das gleiche ist, das heisst, wenn du das als globale Variable in einem Package abspeicherst, und nur noch nachliest, wenn ein anderer Wert, als der dort abgelegte gefragt ist, dann ersparst du dir hier potentiell eine ganze Menge.

> insert into ro\_sp  
> ("proCarId", datum, "chassisNo", "orderNo",  
> "classid", "proId", lastlogin, machine,  
> osuer, program)  
> values  
> (:old."proCarId", sysdate, :old."chassisNo", :old."orderNo",  
> :old."classid", :old."proId", reg2, machine,  
> username, program);  
> END IF;  
>   
> end;  
> /

Da habe ich ausnahmsweise nichts anzumeckern :wink:

Gruß
Martin

Vielen Dank, bin im Prinzip ein Anfänger was
Proceduren und Triggers angeht unter Oracle.

Werd ich mir ansehen und korrigieren.
Nochmals vielen Dank

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]