update trigger tabla misma ejercicios ejemplos campo actualizar 11g oracle plsql triggers error-logging

tabla - trigger oracle insert



¿Cómo desarrollar un disparador after serverror en Oracle? (4)

Compruebe el estado de su activador y / o la existencia de otros desencadenantes con:

select trigger_name, status from all_triggers where triggering_event like ''ERROR%''

Esto debería resultar en:

TRIGGER_NAME STATUS ------------ ------- LOG_SERVER_ERRORS ENABLED

Si el disparador no está habilitado o si falla otro disparador, probablemente no funcionará.

Estoy intentando registrar todos los errores en mi base de datos en una tabla. Entonces, como usuario, escribí el siguiente código:

CREATE TABLE servererror_log ( error_datetime TIMESTAMP, error_user VARCHAR2(30), db_name VARCHAR2(9), error_stack VARCHAR2(2000), captured_sql VARCHAR2(1000)); / CREATE OR REPLACE TRIGGER log_server_errors AFTER SERVERERROR ON DATABASE DECLARE captured_sql VARCHAR2(1000); BEGIN SELECT q.sql_text INTO captured_sql FROM gv$sql q, gv$sql_cursor c, gv$session s WHERE s.audsid = audsid AND s.prev_sql_addr = q.address AND q.address = c.parent_handle; INSERT INTO servererror_log (error_datetime, error_user, db_name, error_stack, captured_sql) VALUES (systimestamp, sys.login_user, sys.database_name, dbms_utility.format_error_stack, captured_sql); END log_server_errors;

Pero cuando fuerzo un error como intentar seleccionar desde una tabla que no existe, no registra el error en la tabla.

¿Hay alguna manera de verificar que el gatillo dispare en absoluto? Además, intenté crear una tabla de prueba para insertar allí, pero tampoco funciona, incluso si defino el activador como una transacción autónoma y me comprometo dentro del desencadenador.

Gracias, Joaquin


Para ver si el disparador se está disparando, agregue una o más líneas de la siguiente manera:

DBMS_OUTPUT.PUT_LINE( ''Got this far'' );

En SQLPlus, SET SERVEROUTPUT ON ejecuta un comando para generar un error. Deberías obtener un resultado como este:

dev> select * from aldfjh; select * from aldfjh * ERROR at line 1: ORA-00942: table or view does not exist ORA-00942: table or view does not exist Got this far


Guarde esto como ORA-00942.sql :

-- Drop trigger and ignore errors (e.g., not exists). DECLARE existential_crisis EXCEPTION; PRAGMA EXCEPTION_INIT( existential_crisis, -4080 ); BEGIN EXECUTE IMMEDIATE ''DROP TRIGGER TRG_CATCH_ERRORS /*+ IF EXISTS */''; EXCEPTION WHEN existential_crisis THEN DBMS_OUTPUT.PUT_LINE(''Ignoring non-existence.''); END; / -- Drop table and ignore errors (e.g., not exists). DECLARE existential_crisis EXCEPTION; PRAGMA EXCEPTION_INIT( existential_crisis, -942 ); BEGIN EXECUTE IMMEDIATE ''DROP TABLE TBL_ERROR_LOG /*+ IF EXISTS */''; EXCEPTION WHEN existential_crisis THEN DBMS_OUTPUT.PUT_LINE(''Ignoring non-existence.''); END; / -- Create the table (will not exist due to drop statement). CREATE TABLE TBL_ERROR_LOG ( occurred timestamp, account varchar2(32), database_name varchar2(32), stack clob, query clob ); -- Create the trigger to log the errors. CREATE TRIGGER TRG_CATCH_ERRORS AFTER servererror ON database DECLARE sql_text ora_name_list_t; n number; query_ clob; BEGIN n := ora_sql_txt( sql_text ); IF n > 1000 THEN n := 1000; END IF; FOR i IN 1 .. n LOOP query_ := query_ || sql_text( i ); END LOOP; INSERT INTO TBL_ERROR_LOG (occurred, account, database_name, stack, query) VALUES (systimestamp, sys.login_user, sys.database_name, dbms_utility.format_error_stack, query_); END; /

Ejecutar usando sqlplus:

SQL> @ORA-00942.sql PL/SQL procedure successfully completed. PL/SQL procedure successfully completed. Table created. Trigger created.

Pruébalo:

select * from blargh; select * from TBL_ERROR_LOG;

Salida:

2017-10-20 15:15:25.061 SCHEMA XE "ORA-00942: table or view does not exist" select * from blargh


No consultar v $ sql; obtener la declaración usando ora_sql_txt.

CREATE OR REPLACE TRIGGER log_server_errors AFTER SERVERERROR ON DATABASE DECLARE sql_text ora_name_list_t; stmt clob; n number; BEGIN n := ora_sql_txt(sql_text); if n > 1000 then n:= 1000; end if ; FOR i IN 1..n LOOP stmt := stmt || sql_text(i); END LOOP; INSERT INTO servererror_log (error_datetime, error_user, db_name, error_stack, captured_sql) VALUES (systimestamp, sys.login_user, sys.database_name, dbms_utility.format_error_stack, stmt); commit; END log_server_errors; /

Entonces:

SQL> select * from c;

Esto produce:

select * from c * ERROR at line 1: ORA-00942: table or view does not exist

Eso ahora puede ser consultado:

select * from servererror_log;

Para producir:

ERROR_DATETIME --------------------------------------------------------------------------- ERROR_USER DB_NAME ------------------------------ --------- ERROR_STACK -------------------------------------------------------------------------------- CAPTURED_SQL -------------------------------------------------------------------------------- 11-FEB-09 02.55.35.591259 PM SYS TS.WORLD ORA-00942: table or view does not exist select * from c