2008년 4월 2일 수요일

JAVA: USE ORACLE CLOB IN JDBC


public static Clob getClob(String clobValue, Connection conn) throws Exception{
Clob newClob= null;
if(clobValue!=null) {
try{
newClob = oracle.sql.CLOB.createTemporary(conn, true, oracle.sql.CLOB.DURATION_SESSION);
if(newClob!=null) {
((oracle.sql.CLOB)newClob).putString(1, clobValue);
}
} catch (Exception e){
}
}
return newClob;
}


입력 시에는 이런식으로 Clob타잎을 생성한후에 preparestatement의 setClob()을 사용 하면 된다.
버그가 있다고는 하는데.. 아직 경험해 보지는 못했다.
결국 경험하게 되었다. pooling된 connection에서는 작동하지 않는다.
다시 해결 방법을 찾았다. http://wiki.caucho.com/Database_FAQ67890




Will the pool be automocatically set to queue if number of connections requested
is more than max connections?
You mean block the waiting thread. Yes.
"queue" doesn't make sense in this context.
If you're using the
PooledDataSource instead of the Driver SPI, you'll get the Oracle connection
directly.
Otherwise, you need to case the Connection to
com.caucho.sql.UserConnectionAdapter and call getConnection() to get the
underlying Oracle connection.


코드는 이렇게 바뀐다.

newClob = oracle.sql.CLOB.createTemporary (((com.caucho.sql.UserConnectionAdapter)conn).getConnection() , true, oracle.sql.CLOB.DURATION_SESSION);

resin의 connection adapter에서 oracle의 connection을 반환하여 처리 한다.

그리고 조회 시에는 이런 식으로 받아 올 수가 있다. CLOB의 stringValue()라는 녀석을 쓰면 딱 좋겠지만 써보면 'java.sql.SQLException: Conversion to String failed' 에러를 내버린다.

다시 에러 발생. jennifer를 사용 할 경우 rapper class가 2중으로 되어 버려서 위의 방법으로
underlying connection을 얻을 수 없다.
http://www.caucho.com/resin-javadoc/com/caucho/sql/UserConnection.html
일단 자료 수집중.

resin 3.0 이상에서는 UserConnection 에 unwrap() method가 있어서 별 문제 없어 보이긴 하나 현제 환경은 resin 2.1이라는게 문제.



CLOB c = (CLOB)rs.getClob(1);
matchInfo.setIntro( c.getSubString(1, (int)c.length()) );


베베 꼬아서 jdbc를 개발한 오라클 놈들에게 박수를 보내며...

이게 도움이 될지는 모르겠지만...
// first, create statement to insert
OraclePreparedStatement ps;
ps = (OraclePreparedStatement )con.prepareStatement("INSERT INTO Test (text) VALUES (?)");

// create a temporary CLOB and write to it
CLOB clob = CLOB.createTemporary(con, true, CLOB.DURATION_SESSION);
Writer out = clob.getCharacterOutputStream();
out.write(myLongText);

// set the CLOB on the OraclePreparedStatement and execute
ps.setCLOB(1, clob);
ps.executeUpdate();


이것도

댓글 없음: