tipos procedimientos procedimiento funciones example español ejemplos ejemplo ejecutar developer bloques almacenado 11g sql oracle plsql dbms-output

procedimientos - ¿Hay alguna manera de descargar la salida de PL/SQL en Oracle?



procedimientos y funciones oracle pl/sql (5)

Dos alternativas:

  1. Puede insertar sus detalles de registro en una tabla de registro mediante el uso de una transacción autónoma. Puede consultar esta tabla de registro en otra sesión de SQLPLUS / Toad / sql developer etc .... Debe utilizar una transacción autónoma para que sea posible confirmar su registro sin interferir en el manejo de la transacción en su script sql principal.

  2. Otra alternativa es usar una función canalizada que devuelva su información de registro. Vea aquí para un ejemplo: http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html Cuando usa una función pipeline no necesita usar otro desarrollador SQLPLUS / Toad / sql, etc. ... sesión.

Tengo un script SQL que se llama desde un script de shell y tarda mucho tiempo en ejecutarse. Actualmente contiene instrucciones dbms_output.put_line en varios puntos. El resultado de estas instrucciones de impresión aparece en los archivos de registro, pero solo una vez que se ha completado.

¿Hay alguna forma de garantizar que el resultado aparezca en el archivo de registro a medida que se ejecuta el script?


Realmente no. La forma en que DBMS_OUTPUT funciona es la siguiente: tu bloque PL / SQL se ejecuta en el servidor de la base de datos sin interacción con el cliente. Entonces, cuando llamas a PUT_LINE, solo estás poniendo ese texto en un búfer en la memoria del servidor. Cuando se completa el bloque PL / SQL, se devuelve el control al cliente (supongo que SQLPlus en este caso); en ese punto, el cliente saca el texto del búfer llamando a GET_LINE y lo muestra.

Por lo tanto, la única forma en que puede hacer que la salida aparezca en el archivo de registro con más frecuencia es dividir un bloque grande de PL / SQL en varios bloques más pequeños, por lo que el control se devuelve al cliente con más frecuencia. Esto puede no ser práctico dependiendo de lo que esté haciendo su código.

Otras alternativas son usar UTL_FILE para escribir en un archivo de texto, que puede eliminarse cuando lo desee, o usar un procedimiento de transacción autónoma para insertar instrucciones de depuración en una tabla de base de datos y confirmar después de cada una.


Si es posible para usted, debe reemplazar las llamadas a dbms_output.put_line por su propia función.

Aquí está el código para esta función WRITE_LOG - si desea tener la capacidad de elegir entre 2 soluciones de registro:

escribir registros en una tabla en una transacción autónoma

CREATE OR REPLACE PROCEDURE to_dbg_table(p_log varchar2) -- table mode: -- requires -- CREATE TABLE dbg (u varchar2(200) --- username -- , d timestamp --- date -- , l varchar2(4000) --- log -- ); AS pragma autonomous_transaction; BEGIN insert into dbg(u, d, l) values (user, sysdate, p_log); commit; END to_dbg_table; /

o escribe directamente en el servidor de BD que aloja tu base de datos

Esto usa el directorio de Oracle TMP_DIR

CREATE OR REPLACE PROCEDURE to_dbg_file(p_fname varchar2, p_log varchar2) -- file mode: -- requires --- CREATE OR REPLACE DIRECTORY TMP_DIR as ''/directory/where/oracle/can/write/on/DB_server/''; AS l_file utl_file.file_type; BEGIN l_file := utl_file.fopen(''TMP_DIR'', p_fname, ''A''); utl_file.put_line(l_file, p_log); utl_file.fflush(l_file); utl_file.fclose(l_file); END to_dbg_file; /


WRITE_LOG

Luego, el procedimiento WRITE_LOG que puede cambiar entre los 2 usos, o puede desactivarse para evitar la pérdida de rendimiento ( g_DEBUG:=FALSE ).

CREATE OR REPLACE PROCEDURE write_log(p_log varchar2) AS -- g_DEBUG can be set as a package variable defaulted to FALSE -- then change it when debugging is required g_DEBUG boolean := true; -- the log file name can be set with several methods... g_logfname varchar2(32767) := ''my_output.log''; -- choose between 2 logging solutions: -- file mode: g_TYPE varchar2(7):= ''file''; -- table mode: --g_TYPE varchar2(7):= ''table''; ----------------------------------------------------------------- BEGIN if g_DEBUG then if g_TYPE=''file'' then to_dbg_file(g_logfname, p_log); elsif g_TYPE=''table'' then to_dbg_table(p_log); end if; end if; END write_log; /

Y aquí está cómo probar lo anterior:

1) Inicie esto ( modo de archivo ) desde su SQLPLUS:

BEGIN write_log(''this is a test''); for i in 1..100 loop DBMS_LOCK.sleep(1); write_log(''iter='' || i); end loop; write_log(''test complete''); END; /

2) en el servidor de la base de datos, abra un shell y

tail -f -n500 /directory/where/oracle/can/write/on/DB_server/my_output.log


Si tiene acceso al shell del sistema desde el entorno PL / SQL puede llamar a netcat:

BEGIN RUN_SHELL(''echo "''||p_msg||''" | nc ''||p_host||'' ''||p_port||'' -w 5''); END;

p_msg - es un mensaje de registro v_host es un host que ejecuta una secuencia de comandos python que lee datos del socket en el puerto v_port .

aplogr este diseño cuando escribí aplogr para monitoreo de registros de shell y pl / sql en tiempo real.


el búfer de DBMS_OUTPUT se lee cuando se llama al procedimiento DBMS_OUTPUT.get_line . Si su aplicación cliente es SQL * Plus, significa que solo se enjuagará una vez que el procedimiento finalice.

Puede aplicar el método descrito en este SO para escribir el búfer DBMS_OUTPUT en un archivo.