복붙노트

[SQL] 오라클 PL / SQL에서 플러시 출력 할 수있는 방법이 있습니까?

SQL

오라클 PL / SQL에서 플러시 출력 할 수있는 방법이 있습니까?

나는 쉘 스크립트 내에서 호출하고 실행하는 데 시간이 오래 소요되는 SQL 스크립트가 있습니다. 그것은 현재 다양한 지점에서 DBMS_OUTPUT.PUT_LINE 문이 포함되어 있습니다. 이러한 인쇄 진술의 출력은 로그 파일에 표시하지만, 한 번만 스크립트가 완료되었습니다.

스크립트와 로그 파일에 출력이 나타납니다가 실행 중인지 확인하는 방법은 없나요?

해결법

  1. ==============================

    1.정말. DBMS_OUTPUT 작동 방법은 이것이다 : 클라이언트와 어떤 상호 작용 데이터베이스 서버에 PL / SQL 블록 실행합니다. 그래서 당신은 단지 서버의 메모리에 버퍼에 텍스트를 가하고, PUT_LINE를 호출 할 때. 당신의 PL / SQL 블록 완료는, 제어는 클라이언트 (I이 경우 SQLPLUS를 있으리라 믿고있어)에 반환 될 때; 그 시점에서 클라이언트를 GET_LINE를 호출하고 표시하여 버퍼 중 텍스트를 가져옵니다.

    정말. DBMS_OUTPUT 작동 방법은 이것이다 : 클라이언트와 어떤 상호 작용 데이터베이스 서버에 PL / SQL 블록 실행합니다. 그래서 당신은 단지 서버의 메모리에 버퍼에 텍스트를 가하고, PUT_LINE를 호출 할 때. 당신의 PL / SQL 블록 완료는, 제어는 클라이언트 (I이 경우 SQLPLUS를 있으리라 믿고있어)에 반환 될 때; 그 시점에서 클라이언트를 GET_LINE를 호출하고 표시하여 버퍼 중 텍스트를 가져옵니다.

    당신은 출력을 할 수있는 유일한 방법은 로그 파일에 나타나도록 제어가 더 자주 클라이언트에 반환되도록 더 자주, 여러 개의 작은 블록으로 큰 PL / SQL 블록을 파괴하는 것입니다. 이 코드가 무엇을하고 있는지에 따라 실용적이지 않을 수 있습니다.

    다른 대안은 언제든지 플러시 할 수있는 텍스트 파일에 쓰기에 UTL_FILE을 사용하거나 데이터베이스 테이블에 디버그 문을 삽입하고 각 한 후 커밋 자율 트랜잭션의 절차를 사용한다.

  2. ==============================

    2.그것은 당신이 할 수 있다면, 당신은 당신의 자신의 기능에 의해 DBMS_OUTPUT.PUT_LINE에 대한 호출을 교체해야합니다.

    그것은 당신이 할 수 있다면, 당신은 당신의 자신의 기능에 의해 DBMS_OUTPUT.PUT_LINE에 대한 호출을 교체해야합니다.

    다음은이 기능 WRITE_LOG의 코드입니다 - 당신이 개 로깅 솔루션을 선택할 수있는 능력을 가지고하려는 경우 :

    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;
    /
    

    이는 오라클 디렉토리 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;
    /
    

    이어서 2 개 이용 사이를 전환 할 수 있고, 또는 성능의 손실을 방지하기 위해 비활성화 할 것을 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
    
  3. ==============================

    3.두 대안 :

    두 대안 :

  4. ==============================

    4.프로 시저 DBMS_OUTPUT.get_line가 호출 될 때 DBMS_OUTPUT의 버퍼를 읽습니다. 클라이언트 응용 프로그램이 SQL * Plus를하는 경우, 그것은 단지 절차가 완료되면 플러시 얻을 것을 의미합니다.

    프로 시저 DBMS_OUTPUT.get_line가 호출 될 때 DBMS_OUTPUT의 버퍼를 읽습니다. 클라이언트 응용 프로그램이 SQL * Plus를하는 경우, 그것은 단지 절차가 완료되면 플러시 얻을 것을 의미합니다.

    당신은 DBMS_OUTPUT 파일로 버퍼 쓰기이 SO에 기술 된 방법을 적용 할 수 있습니다.

  5. ==============================

    5.DBMS_APPLICATION_INFO를 사용하여 설정 세션 메타 데이터 모듈 및 / 또는 ACTION (). 예를 들어, OEM와 모니터 :

    DBMS_APPLICATION_INFO를 사용하여 설정 세션 메타 데이터 모듈 및 / 또는 ACTION (). 예를 들어, OEM와 모니터 :

    Module: ArchiveData
    Action: xxx of xxxx
    
  6. ==============================

    6.당신은 당신이 netcat을 호출 할 수 있습니다 PL / SQL 환경에서 시스템 쉘에 액세스 할 수있는 경우 :

    당신은 당신이 netcat을 호출 할 수 있습니다 PL / SQL 환경에서 시스템 쉘에 액세스 할 수있는 경우 :

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

    p_msg - 로그 메시지입니다 v_host 포트 v_port에 소켓에서 데이터를 읽어 호스트 실행 파이썬 스크립트입니다.

    내가 실시간 쉘 및 PL / SQL 로그 모니터링 aplogr을 쓸 때 나는이 디자인을 사용했다.

  7. from https://stackoverflow.com/questions/1472587/is-there-any-way-to-flush-output-from-pl-sql-in-oracle by cc-by-sa and MIT license