복붙노트

[SQL] JDBC를 사용하여 dbms_output.get_lines에서 얻기 출력

SQL

JDBC를 사용하여 dbms_output.get_lines에서 얻기 출력

어떻게 데이터베이스에 개체를 추가로 만들지 않고 JDBC를 사용하여 Java 응용 프로그램에서 오라클의 dbms_output.get_lines의 출력을 얻을 수 있나요?

해결법

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

    1.또한 여기에이 문제에 대해 블로그했습니다. 다음은이 작업을 수행 할 수있는 방법을 보여주는 코드 조각입니다 :

    또한 여기에이 문제에 대해 블로그했습니다. 다음은이 작업을 수행 할 수있는 방법을 보여주는 코드 조각입니다 :

    try (CallableStatement call = c.prepareCall(
        "declare "
      + "  num integer := 1000;" // Adapt this as needed
      + "begin "
    
      // You have to enable buffering any server output that you may want to fetch
      + "  dbms_output.enable();"
    
      // This might as well be a call to third-party stored procedures, etc., whose
      // output you want to capture
      + "  dbms_output.put_line('abc');"
      + "  dbms_output.put_line('hello');"
      + "  dbms_output.put_line('so cool');"
    
      // This is again your call here to capture the output up until now.
      // The below fetching the PL/SQL TABLE type into a SQL cursor works with Oracle 12c.
      // In an 11g version, you'd need an auxiliary SQL TABLE type
      + "  dbms_output.get_lines(?, num);"
    
      // Don't forget this or the buffer will overflow eventually
      + "  dbms_output.disable();"
      + "end;"
    )) {
        call.registerOutParameter(1, Types.ARRAY, "DBMSOUTPUT_LINESARRAY");
        call.execute();
    
        Array array = null;
        try {
            array = call.getArray(1);
            System.out.println(Arrays.asList((Object[]) array.getArray()));
        }
        finally {
            if (array != null)
                array.free();
        }
    }
    

    위의 인쇄합니다 :

    [abc, hello, so cool, null]
    

    참고가 사용하도록 설정하는 것이 / DISABLE 설정은 또한 여러 JDBC 문을 통해이 작업을 수행 할 수 있도록 연결이 넓은 설정이다 :

    try (Connection c = DriverManager.getConnection(url, properties);
         Statement s = c.createStatement()) {
    
        try {
            s.executeUpdate("begin dbms_output.enable(); end;");
            s.executeUpdate("begin dbms_output.put_line('abc'); end;");
            s.executeUpdate("begin dbms_output.put_line('hello'); end;");
            s.executeUpdate("begin dbms_output.put_line('so cool'); end;");
    
            try (CallableStatement call = c.prepareCall(
                "declare "
              + "  num integer := 1000;"
              + "begin "
              + "  dbms_output.get_lines(?, num);"
              + "end;"
            )) {
                call.registerOutParameter(1, Types.ARRAY, "DBMSOUTPUT_LINESARRAY");
                call.execute();
    
                Array array = null;
                try {
                    array = call.getArray(1);
                    System.out.println(Arrays.asList((Object[]) array.getArray()));
                }
                finally {
                    if (array != null)
                        array.free();
                }
            }
        }
        finally {
            s.executeUpdate("begin dbms_output.disable(); end;");
        }
    }
    

    이 기껏해야 1000 개 라인의 고정 된 크기를 가져올 것이라는 점을 유의하십시오. 당신은 PL / SQL에서 루프에 필요하거나 더 많은 라인을 원하는 경우 데이터베이스를 폴링 할 수 있습니다.

    이전에는 한 번에 하나 개의 행을 반환하는 대신 DBMS_OUTPUT.GET_LINE 개별 통화를 제안 편지 삭제 된 대답은 있었다. 나는 DBMS_OUTPUT.GET_LINES과 비교 접근 방식을 벤치마킹 한과 차이가 격렬 - (정말 PL / SQL에서 프로 시저를 호출 큰 차이가없는 경우에도) JDBC에서 호출 배 30 배 느린까지.

    그래서, DBMS_OUTPUT.GET_LINES를 사용하는 방법을 전송하는 벌크 데이터는 확실히 가치가있다. 여기에 벤치 마크에 대한 링크는 다음과 같습니다

    https://blog.jooq.org/2017/12/18/the-cost-of-jdbc-server-roundtrips/

  2. from https://stackoverflow.com/questions/47830370/getting-output-from-dbms-output-get-lines-using-jdbc by cc-by-sa and MIT license