Oracle에서 PL/SQL 출력을 플러시하는 방법이 있습니까?
셸 스크립트 내에서 호출되는 SQL 스크립트가 있어 실행하는 데 시간이 오래 걸립니다.현재 다음을 포함합니다.dbms_output.put_line여러 가지 점에서 진술합니다.이러한 인쇄문의 출력은 로그 파일에 표시됩니다.단, 스크립트가 완료된 후에만 표시됩니다.
스크립트가 실행 중일 때 로그 파일에 출력이 표시되도록 하는 방법이 있습니까?
사실 그렇지 않아요.DBMS_OUTPUT의 동작 방법은 다음과 같습니다.PL/SQL 블록은 클라이언트와의 상호 작용 없이 데이터베이스 서버에서 실행됩니다.그래서 PUT에 전화하면...LINE, 이 텍스트는 서버상의 메모리에 있는 버퍼에 격납되어 있습니다.PL/SQL 블록이 완료되면 제어가 클라이언트에 반환됩니다(이 경우 SQLPlus를 가정합니다).이 시점에서 클라이언트는 GET_LINE을 호출하여 버퍼에서 텍스트를 가져와 표시합니다.
따라서 로그 파일에 출력을 더 자주 표시할 수 있는 유일한 방법은 큰 PL/SQL 블록을 여러 개의 작은 블록으로 분할하는 것입니다.그러면 제어가 클라이언트에 더 자주 반환됩니다.이것은, 코드의 동작에 따라서는 실용적이지 않을 수 있습니다.
다른 방법으로는 UTL_FILE을 사용하여 텍스트파일에 쓰거나 자율 트랜잭션 절차를 사용하여 데이터베이스 테이블에 디버깅문을 삽입하고 각 파일 뒤에 커밋하는 방법도 있습니다.
가능한 경우 dbms_output 호출을 대체해야 합니다.put_line은 사용자 고유의 기능으로 사용할 수 있습니다.
다음은 이 함수의 코드입니다. 2개의 로깅 솔루션 중 하나를 선택할 수 있는 기능을 가진 경우:
자율 트랜잭션의 테이블에 로그 쓰기
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;
/
또는 데이터베이스를 호스트하는 DB 서버에 직접 쓰거나
Oracle 디렉토리를 사용합니다.
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
그런 다음 두 가지 용도를 전환하거나 성능 손실을 방지하기 위해 비활성화할 수 있는 절차(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
두 가지 대안:
Autonomous 트랜잭션을 사용하여 로깅 테이블에 로깅 세부 정보를 삽입할 수 있습니다.다른 SQLPLUS/Toad/sql 개발자 등에서 이 로깅 테이블을 쿼리할 수 있습니다.세션입니다.메인 SQL 스크립트의 트랜잭션 처리를 방해하지 않고 로그를 커밋하려면 자율 트랜잭션을 사용해야 합니다.
또 다른 방법은 로깅 정보를 반환하는 파이프라인 함수를 사용하는 것입니다.예를 들어 http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html 파이프라인 함수를 사용할 경우 다른 SQLPLUS/Toad/sql 개발자 등을 사용할 필요가 없습니다.세션입니다.
of충의 DBMS_OUTPUT.DBMS_OUTPUT.get_line합니다.클라이언트 애플리케이션이 SQL*Plus인 경우 절차가 완료된 후에만 해당 애플리케이션이 플러시됨을 의미합니다.
이 SO에서 설명된 방법을 적용하여 다음을 작성할 수 있습니다.DBMS_OUTPUT파일로 버퍼링합니다.
를 사용하여 및을 설정합니다.dbms_application_info().
OEM을 OEM) §:
Module: ArchiveData
Action: xxx of xxxx
PL/SQL 환경에서 시스템셸에 액세스 할 수 있는 경우는, netcat 를 호출할 수 있습니다.
BEGIN RUN_SHELL('echo "'||p_msg||'" | nc '||p_host||' '||p_port||' -w 5'); END;
p_msg입니다. - 로그 메시지입니다.v_host를 실행하고 이 스크립트는 python 포트 상의 .이 스크립트는 포트 상의 소켓에서 데이터를 읽습니다.v_port.
실시간 셸 및 pl/sql 로그 모니터링을 위해 aplogr을 작성할 때 이 디자인을 사용했습니다.
언급URL : https://stackoverflow.com/questions/1472587/is-there-any-way-to-flush-output-from-pl-sql-in-oracle
'programing' 카테고리의 다른 글
| 만약...엘세...을 사용할 수 있습니까?리액트 렌더 함수에 있는 문? (0) | 2023.03.10 |
|---|---|
| Wordpress에서 session_start를 사용하는 방법 (0) | 2023.03.10 |
| jq에서 해당 키의 키 및 값을 기준으로 json 파일을 정렬하는 방법 (0) | 2023.03.10 |
| 리액션 리덕스 내 성분과 용기의 차이 (0) | 2023.03.10 |
| 각도 html을 렌더링하는 방법JS 템플릿 (0) | 2023.03.10 |