쉘 스크립트 내에서 호출되는 SQL 스크립트가 있으며 실행하는 데 오랜 시간이 걸립니다. 현재 다양한 지점에서 dbms_output.put_line
문장이 포함되어 있습니다. 이러한 인쇄 명령문의 출력은 로그 파일에 표시되지만 스크립트가 완료된 후에 만 표시됩니다.Oracle의 PL/SQL에서 출력을 플러시 할 수 있습니까?
스크립트가 실행 중일 때 출력이 로그 파일에 나타나는지 확인하는 방법이 있습니까?
쉘 스크립트 내에서 호출되는 SQL 스크립트가 있으며 실행하는 데 오랜 시간이 걸립니다. 현재 다양한 지점에서 dbms_output.put_line
문장이 포함되어 있습니다. 이러한 인쇄 명령문의 출력은 로그 파일에 표시되지만 스크립트가 완료된 후에 만 표시됩니다.Oracle의 PL/SQL에서 출력을 플러시 할 수 있습니까?
스크립트가 실행 중일 때 출력이 로그 파일에 나타나는지 확인하는 방법이 있습니까?
아니요. DBMS_OUTPUT이 작동하는 방식은 다음과 같습니다. PL/SQL 블록은 클라이언트와 상호 작용하지 않고 데이터베이스 서버에서 실행됩니다. 따라서 PUT_LINE을 호출하면 서버의 메모리 버퍼에 텍스트가 저장됩니다. PL/SQL 블록이 완료되면 클라이언트 (이 경우 SQLPlus라고 가정)로 제어가 리턴됩니다. 이 시점에서 클라이언트는 GET_LINE을 호출하여 버퍼에서 텍스트를 가져 와서 표시합니다.
출력을 로그 파일에 더 자주 표시 할 수있는 유일한 방법은 대형 PL/SQL 블록을 여러 개의 작은 블록으로 분할하여 제어가 클라이언트에 더 자주 리턴되는 것입니다. 이것은 코드가하는 일에 따라 실용적이지 않을 수 있습니다.
다른 대안은 UTL_FILE을 사용하여 언제든지 삭제할 수있는 텍스트 파일에 쓰거나, 자율 트랜잭션 프로 시저를 사용하여 디버그 문을 데이터베이스 테이블에 삽입하고 각각을 수행 한 후 커밋하는 것입니다.
절차 DBMS_OUTPUT.get_line
을 호출하면 DBMS_OUTPUT
의 버퍼가 읽혀집니다. 클라이언트 응용 프로그램이 SQL * Plus 인 경우 프로 시저가 완료된 후에 만 플러시됩니다.
this SO에 설명 된 방법을 적용하여 DBMS_OUTPUT
버퍼를 파일에 쓸 수 있습니다.
두 대안 :
당신은 자율 트랜잭션을 사용하여 로깅 테이블 로깅 정보를 삽입 할 수 있습니다. 다른 SQLPLUS/Toad/sql 개발자 등 세션에서이 로깅 테이블을 쿼리 할 수 있습니다. 주요 SQL 스크립트에서 트랜잭션 처리를 방해하지 않고 로깅을 커밋 할 수있게하려면 자치 트랜잭션을 사용해야합니다.
또 다른 대안은 로깅 정보를 반환하는 파이프 라인 된 함수를 사용하는 것입니다. 예제를 보려면 다음을 참조하십시오. http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html 파이프 라인 기능을 사용하면 다른 SQLPLUS/Toad/sql 개발자 등 세션을 사용할 필요가 없습니다.
가능한 경우 dbms_output.put_line에 대한 호출을 사용자 고유의 기능으로 바꿔야합니다.여기
이 기능WRITE_LOG
코드입니다 - 당신이 개 로깅 솔루션을 선택할 수있는 능력을 갖고 싶어 :
autonomous transaction 의 테이블에
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;
/
이것은 2 개 용도를 전환하거나 비활성화 t 될 수 Oracle directoryTMP_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
이어서 WRITE_LOG
절차를 사용하여 o 공연 손실을 피하십시오 (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;
/
1) 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), 열려면 쉘 및
tail -f -n500 /directory/where/oracle/can/write/on/DB_server/my_output.log
PL/SQL 환경에서 시스템 쉘에 액세스 할 수있는 경우 당신이 netcat을 호출 할 수 있습니다 했었다는 :
BEGIN RUN_SHELL('echo "'||p_msg||'" | nc '||p_host||' '||p_port||' -w 5'); END;
p_msg
이 - 로그 메시지 v_host
것은 포트 v_port
에 소켓에서 데이터를 읽어 호스트 실행 파이썬 스크립트입니다.
실시간 쉘 및 pl/sql 로그 모니터링을 위해 aplogr을 작성할 때이 디자인을 사용했습니다.
여러 질문에 [같은 대답] (링크)을 추가하지 마십시오. 가장 좋은 답변을하고 나머지는 중복으로 표시하십시오. [여러 질문에 대한 중복 답변을 추가해도됩니까?] (http://meta.stackexchange.com/q/104227/347985)를 참조하십시오. – Mogsdad
아무도 'u, d, l'과 같은 열 이름이있는 테이블을 사용하지 않기를 바랍니다. – Obenland
@ Oberland, 사용자를 처리하는 프레임 워크가 올바른 경우 표 및 열 이름은 중요하지 않습니다. BTW 이전 학교 데이터베이스가있는 은행에서 일해 본 적이 있습니까? 그것보다 가치가 있습니다. –
나는 '나쁜'을 의미한다고 생각합니다.) – quetzalcoatl