2010-09-17 15 views
6

No sé dónde se produce la información de error cuando un desencadenador no funciona correctamente.Técnicas de depuración de Oracle

Mi herramienta para escribir activadores ha sido la herramienta Oracle Sql Developer, y mi conocimiento de cómo depurarlo es prácticamente inexistente. ¿Cuáles son algunos consejos para poder encontrar información útil sobre cosas que suceden "detrás de escena"? Además, ¿hay mejores herramientas que Sql Developer para conectar, probar, depurar, etc.?

Mi método hasta ahora ha sido escribir algo (un disparador, por ejemplo), probarlo con inserciones/eliminaciones individuales, y luego espero que funcione desde ellas. ¿Hay mejores formas de asegurarte de que está haciendo exactamente lo que quieres? Por ejemplo, con una instrucción select, ¿hay alguna forma de ver (en un estado de depuración o algo así) cada nivel de la selección y cómo se ralentiza el resultado? Cualquier consejo muy apreciado.

Respuesta

12

En primer lugar, todo el código funciona correctamente. Simplemente no hace lo que esperabas que hiciera.

En segundo lugar, "No empieces por aquí", o específicamente no uses activadores. Básicamente va a forzar el cambio al procesamiento a nivel de fila si los disparadores van a disparar para cada fila. Es mejor poner la lógica en un procedimiento almacenado al que llamas. Luego has comenzado (donde valides las entradas) y un final y una ruta lógica hasta el final. Son mucho más fáciles de depurar a medida que sigue un camino.

Tres, nunca pruebe un error que no sepa cómo manejarlo. Si no lo captas, surge hasta el cliente que recibe un informe de error que dice qué salió mal (mensaje de error) y dónde (es decir, el error/pila de llamadas). Si intentas atraparlo, debes saber qué hacer con él (y si no sabes, la tendencia es ignorarlo, lo cual es MALO).

Finalmente, no puede ver fácilmente cada 'capa' de una selección. El plan de explicación generalmente le dirá cómo va todo esto. v $ session_longops PUEDE indicar lo que está haciendo actualmente. El evento de espera actual PUEDE dar pistas sobre en qué tabla/bloque/fila está trabajando actualmente.

+0

+1 por mencionar el plan de explicación, y +1 por "todo el código funciona correctamente" :) –

+0

No di información suficiente en mi original.Escribí un disparador que funcionaba en insertos individuales pero no múltiples, creo que debido a un problema de interbloqueo. Creo que solucioné ese problema, pero mientras estaba sucediendo fue un "error silencioso". ¿Hay algún registro o algo en lo que pueda encontrar información así? Otro seguimiento: ¿cómo terminaría un procedimiento almacenado diferente a un Por ejemplo, supongo que tengo una tabla en la que una fuente externa está poniendo datos, y otra tabla en la que quiero poner datos según esa primera tabla, y la mantengo actualizada con los datos actuales. ¿Cómo se almacena el procedimiento> desencadenar allí? –

+0

Hay no hay errores silenciosos. O errores, fallas y vueltas atrás. O tiene éxito pero, muy posiblemente, hace lo que le has dicho que haga no lo que quieres que haga. Porque los disparadores a nivel de fila disparan durante el curso de una Enunciado SQL hay problemas de consistencia de lectura que a menudo conducen a soluciones temporales complejas y propensas a errores. –

10

Un método sencillo y fácil de usar si debe depurar desencadenantes es usar DBMS_OUTPUT.

p. Ej.

SQL> CREATE OR REPLACE TRIGGER mytrigger 
    BEFORE UPDATE ON mytable 
    FOR EACH ROW 
    ... 
    BEGIN 
     DBMS_OUTPUT.put_line('mytrigger STARTING'); 
     ... do some logic ... 
     DBMS_OUTPUT.put_line('old=' || :OLD.mycolumn); 
     DBMS_OUTPUT.put_line('new=' || :NEW.mycolumn); 
     DBMS_OUTPUT.put_line('mytrigger FINISHED'); 
    END; 
    /

SQL> SET SERVEROUT ON 
SQL> UPDATE mytable SET mycolumn = mycolumn + 1; 
2 rows updated. 

mytrigger STARTING 
old=10 
new=11 
mytrigger FINISHED 
mytrigger STARTING 
old=20 
new=21 
mytrigger FINISHED 
+0

Buena información, gracias. –

1

Aplicación que usar un programa de búsqueda llamada SAPO disponible en www.quest.com/toad/toad-for-oracle.aspx.

Como se mencionó anteriormente, DBMS_OUTPUT es muy útil. En su editor, asegúrese de habilitar la ventana de Salida.

PL/SQL funciona en "bloques" de código y puede capturarlo con una palabra clave EXCEPTION.

(Por favor, perdona mi formato, sin saber cómo dar formato para web)

DECLARE 
    C_DATE_FORMAT VARCHAR2(20) := 'DD-Mon-YYYY'; 
    C_TIME_FORMAT VARCHAR2(20) := 'HH24:MI:SS'; 
    C_NOT_IMPLEMENTED_CODE CONSTANT NUMBER(5) := -20200; 
    C_NOT_IMPLEMENTED_MESSAGE CONSTANT VARCHAR2(255) := 'Not implemented'; 
    not_implemented EXCEPTION; -- user defined exception 
BEGIN 
    --RAISE not_implemented; -- raise user defined exception 
    RAISE_APPLICATION_ERROR(C_NOT_IMPLEMENTED_CODE, C_NOT_IMPLEMENTED_MESSAGE); -- user defined exception 
EXCEPTION -- exception block 
    WHEN not_implemented THEN -- catch not_implemented exception 
     DBMS_OUTPUT.PUT_LINE('Error: Not implemented'); 
    WHEN OTHERS THEN -- catch all other exceptions 
     DBMS_OUTPUT.PUT_LINE('Error occured.'); 
     DBMS_OUTPUT.PUT_LINE('Date: ' || TO_CHAR(SYSDATE, C_DATE_FORMAT)); 
     DBMS_OUTPUT.PUT_LINE('Time: ' || TO_CHAR(SYSDATE, C_TIME_FORMAT)); 
     DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE); 
     DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM); --deal with error 
     RAISE; -- raise to calling object 
END; 
0

También hay una buena herramienta Oracle debugger en dbForge Studio for Oracle con ejecución de código paso a paso, puntos de interrupción, una pila de llamadas, relojes, un mecanismo de evaluación de variables para las funciones almacenadas de Oracle y la automatización de depuración de procedimientos.

Cuestiones relacionadas