어떻게 자바 코드 에서 dbms 를 얻 습 니까?output 결과
먼저 옮 겨 싣 고 시간 나 면 번역 하 세 요.강박 하 다.
You Asked
I'm using a Java application to process an incoming feed. The app inserts data into some
Oracle tables, then runs an Oracle stored procedure. The Java application is called from
a UNIX script, connects to Oracle using Oracle's thin client driver and sends output to
standard out. In the existing Oracle stored procedure, there are calls to
DBMS_OUTPUT.put_line(...). The output of the app does not contain results of the
DBMS_OUTPUT.put_line calls.
I know that the UNIX script that calls the java app could be changed to make a call to
PL/SQL with the first line being something like, "set serveroutput on size 999999", then
call the stored procedure instead of calling the stored procedure from JDBC, and I would
see the output in the script's log. I'd rather avoid doing this if possible.
Is there a way to either:
1) Use some other Oracle function instead of DBMS_OUTPUT.put_line() which will send data
to standard out
or
2) Somehow configure the JDBC driver in a way that I haven't yet discovered.
or
3) Some other clever suggestion you have.
Thank you very much for any thoughts.
and we said...
Here is an excerpt from my book "Expert One on One Oracle" about dbms_output - it shows
how to teach other environments to be dbms_outupt aware:
Teaching other environments about DBMS_OUTPUT
By default, tools such as SQL*PLUS and SVRMGRL are DBMS_OUTPUT aware. Most other
environments are not. For example, your Java/JDBC program is definitely not DBMS_OUTPUT
aware. We'll see in this section how to make Java/JDBC DBMS_OUTPUT aware. The same
principles used below apply equally to any programming environment. The methods I use
with Java can be easily applied to Pro*C, OCI, VB or any number of programmatic
environments.
We'll start with a small PL/SQL routine that generates some output data:
scott@TKYTE816> create or replace
2 procedure emp_report
3 as
4 begin
5 dbms_output.put_line
6 ( rpad( 'Empno', 7 ) ||
7 rpad('Ename',12) ||
8 rpad('Job',11) );
9
10 dbms_output.put_line
11 ( rpad( '-', 5, '-' ) ||
12 rpad(' -',12,'-') ||
13 rpad(' -',11,'-') );
14
15 for x in ( select * from emp )
16 loop
17 dbms_output.put_line
18 ( to_char( x.empno, '9999' ) || ' ' ||
19 rpad( x.ename, 12 ) ||
20 rpad( x.job, 11 ) );
21 end loop;
22 end;
23 /
Procedure created.
scott@TKYTE816> set serveroutput on format wrapped
scott@TKYTE816> exec emp_report
Empno Ename Job
----- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
…
7934 MILLER CLERK
PL/SQL procedure successfully completed.
Now, we'll set up a class to allow Java/JDBC to easily perform DBMS_OUTPUT for us.
import java.sql.*;
class DbmsOutput
{
/*
* our instance variables. It is always best to
* use callable or prepared statements and prepare (parse)
* them once per program execution, rather then one per
* execution in the program. The cost of reparsing is
* very high. Also -- make sure to use BIND VARIABLES!
*
* we use three statments in this class. One to enable
* dbms_output - equivalent to SET SERVEROUTPUT on in SQL*PLUS.
* another to disable it -- like SET SERVEROUTPUT OFF.
* the last is to "dump" or display the results from dbms_output
* using system.out
*
*/
private CallableStatement enable_stmt;
private CallableStatement disable_stmt;
private CallableStatement show_stmt;
/*
* our constructor simply prepares the three
* statements we plan on executing.
*
* the statement we prepare for SHOW is a block of
* code to return a String of dbms_output output. Normally,
* you might bind to a PLSQL table type but the jdbc drivers
* don't support PLSQL table types -- hence we get the output
* and concatenate it into a string. We will retrieve at least
* one line of output -- so we may exceed your MAXBYTES parameter
* below. If you set MAXBYTES to 10 and the first line is 100
* bytes long, you will get the 100 bytes. MAXBYTES will stop us
* from getting yet another line but it will not chunk up a line.
*
*/
public DbmsOutput( Connection conn ) throws SQLException
{
enable_stmt = conn.prepareCall( "begin dbms_output.enable(:1); end;" );
disable_stmt = conn.prepareCall( "begin dbms_output.disable; end;" );
show_stmt = conn.prepareCall(
"declare " +
" l_line varchar2(255); " +
" l_done number; " +
" l_buffer long; " +
"begin " +
" loop " +
" exit when length(l_buffer)+255 > :maxbytes OR l_done = 1; " +
" dbms_output.get_line( l_line, l_done ); " +
" l_buffer := l_buffer || l_line || chr(10); " +
" end loop; " +
" :done := l_done; " +
" :buffer := l_buffer; " +
"end;" );
}
/*
* enable simply sets your size and executes
* the dbms_output.enable call
*
*/
public void enable( int size ) throws SQLException
{
enable_stmt.setInt( 1, size );
enable_stmt.executeUpdate();
}
/*
* disable only has to execute the dbms_output.disable call
*/
public void disable() throws SQLException
{
disable_stmt.executeUpdate();
}
/*
* show does most of the work. It loops over
* all of the dbms_output data, fetching it in this
* case 32,000 bytes at a time (give or take 255 bytes).
* It will print this output on stdout by default (just
* reset what System.out is to change or redirect this
* output).
*/
public void show() throws SQLException
{
int done = 0;
show_stmt.registerOutParameter( 2, java.sql.Types.INTEGER );
show_stmt.registerOutParameter( 3, java.sql.Types.VARCHAR );
for(;;)
{
show_stmt.setInt( 1, 32000 );
show_stmt.executeUpdate();
System.out.print( show_stmt.getString(3) );
if ( (done = show_stmt.getInt(2)) == 1 ) break;
}
}
/*
* close closes the callable statements associated with
* the DbmsOutput class. Call this if you allocate a DbmsOutput
* statement on the stack and it is going to go out of scope --
* just as you would with any callable statement, result set
* and so on.
*/
public void close() throws SQLException
{
enable_stmt.close();
disable_stmt.close();
show_stmt.close();
}
}
In order to demonstrate its use, I've set up the following small Java/JDBC test program.
Here dbserver is the name of the database server and ora8i is the service name of the
instance:
import java.sql.*;
class test {
public static void main (String args [])
throws SQLException
{
DriverManager.registerDriver
(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection
("jdbc:oracle:thin:@dbserver:1521:ora8i",
"scott", "tiger");
conn.setAutoCommit (false);
Statement stmt = conn.createStatement();
DbmsOutput dbmsOutput = new DbmsOutput( conn );
dbmsOutput.enable( 1000000 );
stmt.execute
( "begin emp_report; end;" );
stmt.close();
dbmsOutput.show();
dbmsOutput.close();
conn.close();
}
}
Now we will test it, by first compiling it and then running it:
$ javac test.java
$ java test
Empno Ename Job
----- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
……
So, that shows how to teach Java to do DBMS_OUTPUT for us. Just as SQL*PLUS does, you'll
have to call DbmsOutput.show() after executing any statement that might procedure some
output to be displayed. After we execute an insert, update, delete or stored procedure
call – SQL*PLUS is calling DBMS_OUTPUT.GET_LINES to get the output. Your Java (or C, or
VB) application would call 'show' to display the results.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.