[Oracle PL/SQL] - Trigger di Sistema x eseguire 'SET SERVEROUTPUT ON'...

giovedì 28 aprile 2011 - 22.57

lello82nap Profilo | Newbie


Ciao ragazzi
sono alle prime armi con Oracle e SQLPLUS
siccome nella mia base di dati uso spesso DBMS_OUTPUT.PUT_LINE ho bisogno di un trigger che ad ogni accesso al database da parte di qualsiasi uttente esegua in automatico il comando
"SET SERVEROUTPUT ON" x aprire il buffer di visualizzazione di DBMS_OUTPUT.PUT_LINE
e non dover così digitare il comando ogni volta!

avevo pensato a qualcosa come

CREATE OR REPLACE TRIGGER SystemSettingsMedicasa
AFTER LOGON ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'SET SERVEROUTPUT ON';
END;

Purtroppo non funziona perchè credo che EXECUTE IMMEDIATE funzioni solo con comandi Oracle SQL e blocchi PL/SQL, mentre SET SERVEROUTPUT ON è un comando dell'interfaccia SQLplus

come posso risolvere questo problema?

micto27 Profilo | Senior Member

Ciao,
io sinceramente punterei definire una tabella di log nella quale inserire le informazioni piuttosto che usare PUT_LINE

la scrittura su tale tabella di log potrebbe essere effettuata da una PROCEDURE, ad esempio
CREATE OR REPLACE PROCEDURE writelog(msg VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO tabellalog (logmess) VALUES (msg); COMMIT; END writelog; /

PRAGMA AUTONOMOUS_TRANSACTION; serve per far lavorare la procedura in una transazione separata,
in questo modo anche in caso di eccezione nel trigger la transazione viene annullata, però ciò che eseguirebbe
la procedura di scrittura log sarebbe consolidato a parte e quindi le righe sul log le troveresti comunque,
anche con il ROLLBACK della transazione principale.

nell'esempio la tabella usata nell'insert è banale, però oltre al messaggio potresti prevedere una serie di colonne di contesto ricavabili automaticamente,
ad esempio
DATA di inserimento
UTENTE connesso
NOME DELLA MACCHINA che sta connettendo il db, ecc.

prova per curiosità ad eseguire la seguente query per farti un'idea delle informazioni che potresti ricavare dal contesto di esecuzione,
alcune di queste informazioni potrebbero essere comode a corredo del log.

select SYS_CONTEXT('USERENV','TERMINAL') terminal, SYS_CONTEXT('USERENV','LANGUAGE') language, SYS_CONTEXT('USERENV','SESSIONID') sessionid, SYS_CONTEXT('USERENV','INSTANCE') instance, SYS_CONTEXT('USERENV','ENTRYID') entryid, SYS_CONTEXT('USERENV','ISDBA') isdba, SYS_CONTEXT('USERENV','NLS_TERRITORY') nls_territory, SYS_CONTEXT('USERENV','NLS_CURRENCY') nls_currency, SYS_CONTEXT('USERENV','NLS_CALENDAR') nls_calendar, SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') nls_date_format, SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE') nls_date_language, SYS_CONTEXT('USERENV','NLS_SORT') nls_sort, SYS_CONTEXT('USERENV','CURRENT_USER') current_user, SYS_CONTEXT('USERENV','CURRENT_USERID') current_userid, SYS_CONTEXT('USERENV','SESSION_USER') session_user, SYS_CONTEXT('USERENV','SESSION_USERID') session_userid, SYS_CONTEXT('USERENV','PROXY_USER') proxy_user, SYS_CONTEXT('USERENV','PROXY_USERID') proxy_userid, SYS_CONTEXT('USERENV','DB_DOMAIN') db_domain, SYS_CONTEXT('USERENV','DB_NAME') db_name, SYS_CONTEXT('USERENV','HOST') host, SYS_CONTEXT('USERENV','OS_USER') os_user, SYS_CONTEXT('USERENV','EXTERNAL_NAME') external_name, SYS_CONTEXT('USERENV','IP_ADDRESS') ip_address, SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') network_protocol, SYS_CONTEXT('USERENV','BG_JOB_ID') bg_job_id, SYS_CONTEXT('USERENV','FG_JOB_ID') fg_job_id, SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE') authentication_type, SYS_CONTEXT('USERENV','AUTHENTICATION_DATA') authentication_data, SYS_CONTEXT('USERENV','CURRENT_SQL') current_sql, SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER') client_identifier, SYS_CONTEXT('USERENV','GLOBAL_CONTEXT_MEMORY') global_context_memory from dual;

Ciao, Michele

lello82nap Profilo | Newbie

Ciao Mikyyyyyyyyyyyyyyyyyyyy :-)
Ma io gia ce l'ho una tabella di Log e un trigger che mi funziona su di essa, lo feci una settimana fa e funziona bene. :-)
Forse ti sei confuso e volevi rispondere ad un altro thread?

Quello che devo fare io è solo un semplice trigger per far partire SET SERVEROUTPUT ON ogni volta che si avvia una sessione di oracle,
per evitare che un ipotetico utente inesperto debba digitarla a mano dopo ogni login. E nella mia inesperienza suppongo che una cosa del genere si debba fare con un trigger di sistema.
i PUT_LINE che mi serve visualizzare e di cui ti parlo sono quelli che gia ho usato in altri trigger e procedure x inviare messaggi informativi a video. dicevo in quel senso lì, SERVEROUTPUT ON mi serve per visualizzare quelli. :-)
io avevo in mente una cosa tipo l a seguente

CREATE OR REPLACE TRIGGER attivaServeroutput
AFTER LOGON ON DATABASE
BEGIN
----- esegui comando 'SET SERVEROUTPUT ON'
END;

ma come l'ho implementata io con EXECUTE IMMEDIATE non funziona perchè questo comando funge solo con comandi SLQ e PL/SQL
mentre se non sbaglio SET SERVEROUTPUT [ON/OFF] mi pare sia un comando SQLplus.
Come devo fare?

micto27 Profilo | Senior Member

>Ciao Mikyyyyyyyyyyyyyyyyyyyy :-)
>Ma io gia ce l'ho una tabella di Log e un trigger che mi funziona
>su di essa, lo feci una settimana fa e funziona bene. :-)
>Forse ti sei confuso e volevi rispondere ad un altro thread?
>

non pensavo ad un altro thread... però in effetti mi sono spiegato male.
Semplicemente era solo perchè non mi convinceva più di tanto mettere il PUT_LINE in un trigger.
Per quanto riguarda l'utilizzo di EXECUTE IMMEDIATE...
riguarda solo DDL e DML.
>
>CREATE OR REPLACE TRIGGER attivaServeroutput
>AFTER LOGON ON DATABASE
>BEGIN
>----- esegui comando 'SET SERVEROUTPUT ON'
>END;
>
>ma come l'ho implementata io con EXECUTE IMMEDIATE non funziona
>perchè questo comando funge solo con comandi SLQ e PL/SQL
>mentre se non sbaglio SET SERVEROUTPUT [ON/OFF] mi pare sia un
>comando SQLplus.
>Come devo fare?
>

invece di EXECUTE IMMEDIATE 'xxxxxxxxxxxxxxxxxxx'
prova ad eseguire DBMS_OUTPUT.ENABLE

credo che alla fine eseguendo con SQLPLUS il comando SET SERVEROUTPUT ON
venga proprio invocato DBMS_OUTPUT.ENABLE

vedi http://www.adp-gmbh.ch/ora/sqlplus/serveroutput.html

Michele

lello82nap Profilo | Newbie

provato con enable in questo modo:

CREATE OR REPLACE TRIGGER AttivaBufferDBMS
AFTER LOGON ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'dbms_output.enable';
END;

ma non funziona lo stesso.

ho letto l'articolo che mi hai passato, ma x quel che ho tradotto significa che la server output on attiva il server e poi abilita il buffer con dbms_output.enable chiamando automaticamente questa, ma chiamare dbms_output.enable non implica di conseguenza l'attivazione del serveroutput on.

in pratica set serveroutput on = attiva il server di output + attiva buffer
mentre dbms_output.enable = attiva solo il buffer ma non il server

nella mia ignoranza spero di aver capito bene

micto27 Profilo | Senior Member

>provato con enable in questo modo:
>
>CREATE OR REPLACE TRIGGER AttivaBufferDBMS
>AFTER LOGON ON DATABASE
>BEGIN
>EXECUTE IMMEDIATE 'dbms_output.enable';
>END;
>
>ma non funziona lo stesso.

non mettere EXECUTE IMMEDIATE

semplicemente
BEGIN
dbms_output.enable;
END;

ciao

>
>ho letto l'articolo che mi hai passato, ma x quel che ho tradotto
>significa che la server output on attiva il server e poi abilita
>il buffer con dbms_output.enable chiamando automaticamente questa,
>ma chiamare dbms_output.enable non implica di conseguenza l'attivazione
>del serveroutput on.
>
>in pratica set serveroutput on = attiva il server di output +
>attiva buffer
>mentre dbms_output.enable = attiva solo il buffer ma non il server
>
>nella mia ignoranza spero di aver capito bene

lello82nap Profilo | Newbie

neanche in questo modo
ho provato adesso anche questa ma non va

micto27 Profilo | Senior Member

>neanche in questo modo
>ho provato adesso anche questa ma non va

Allora..
cambiamo strada.

SET SERVEROUTPUT ON oltre ad invocare dbms_output.enable fa si che i messaggi vengano visualizzati nella finestra
dove si sta operando con SQLPLUS.

A questo punto lasciamo stare i TRIGGER e va a configurarti il file contenente le istruzioni processate da SQLPLUS ad ogni login.
Cerca un file denominato glogin.sql (sulla mia macchina è in questa directory: oracle\product\10.2.0\db_1\sqlplus\admin)
e aggiungi SET SERVEROUTPUT ON in tale file.

Salva e prova ad eseguire sqlplus.

Ciao

lello82nap Profilo | Newbie

Michele, te lo dico in CAPS:

MI PROSTRO AI TUOI PIEDI!! SEI UN GENIO!!

Ho modificato il file glogin come hai detto, e non sorge piu' problema!
Sei un Magooooooooooooooooo!!! GRAZIE INFINITE :-D E SEMPRE A DISPOSIZIONE
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5