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