현상
1.
바인드 변수를 쿼리 내에 직접 넣어 Tibero tbsql 수행 시 정상적으로 수행시 정상 수행됩니다.
2.
바인드 변수 Tibero tbsql 쿼리에 선언하여 수행 시 정상 수행됩니다.
3.
JDBC PreparedStatement 처리 시 ORA-00911 invalid character 에러 발생하며 수행 불가한 오류가 발생합니다.
참고
Tibero7.2.1 버전에서 발생한 문제 현상입니다.
아래는 JDBC 에러 내용입니다.
•
java.sql.SQLException: JDBC-12126:Remote database client API error - (ORA-00911) 사용 불가한 오류 발생 확인
•
재현 시나리오
<Oracle>
create table t1(c1 number, c2 varchar(8));
insert into t1 values(1, '10');
insert into t1 values(2, '20');
insert into t1 values(3, '30');
commit;
<Tibero>
create table t2(c1 number, c2 varchar(8));
insert into t2 values(1, '10');
insert into t2 values(2, '20');
insert into t2 values(3, '30');
<DB link 생성>
create database link olink connect to xxx identified by 'xxx' using 'xxx';
commit;
<jdbc 사용 X, 티베로에서 바인딩 변수 처리 후 수행시 정상 수행>
var b1 varchar(10);
exec :b1 := '20';
SELECT * FROM t1@olink t1, t2 where t1.c2 = t2.c2 and t1.c2 = :b1;
<test.java 파일 생성>
public class test {
public static void main(String[] args) {
try {
Class.forName("com.tmax.tibero.jdbc.TbDriver");
Connection conn = DriverManager.getConnection("jdbc:tibero:thin:@localhost:28485:tibero","tibero","tmax");
System.out.println("db connection!");
String sql="SELECT * FROM t1@olink t1, t2 where t1.c2 = t2.c2 and t1.c2 = ?";
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "20");
ResultSet rs=pstmt.executeQuery();
while(rs.next()) {
System.out.println(rs.getString(1));
}
}catch(Exception e){
e.printStackTrace();
}
}
}
<java 파일 실행>
tibero7 [develop]+>$ javac test.java
tibero7 [develop]+>$ java -classpath .:$TB_HOME/client/lib/jar/tibero7-jdbc-dbg.jar test
<실행 결과>
java.sql.SQLException: JDBC-12126:Remote database client API error - (ORA-00911) invalid character
at com.tmax.tibero.jdbc.err.TbError.makeSQLException(TbError.java:484)
at com.tmax.tibero.jdbc.err.TbError.newSQLException(TbError.java:549)
at com.tmax.tibero.jdbc.msg.common.TbMsgError.readErrorStackInfo(TbMsgError.java:109)
at com.tmax.tibero.jdbc.msg.TbMsgEreply.deserialize(TbMsgEreply.java:31)
at com.tmax.tibero.jdbc.comm.TbStream.readMsg(TbStream.java:476)
at com.tmax.tibero.jdbc.comm.TbCommType4.prepareExecute(TbCommType4.java:3082)
at com.tmax.tibero.jdbc.driver.TbPreparedStatementImpl.executeCompleteSQL(TbPreparedStatementImpl.java:1175)
at com.tmax.tibero.jdbc.driver.TbPreparedStatementImpl.executeInternal(TbPreparedStatementImpl.java:1314)
at com.tmax.tibero.jdbc.driver.TbPreparedStatementImpl.executeQuery(TbPreparedStatementImpl.java:1380)
at com.tmax.tibero.jdbc.driver.TbPreparedStatement.executeQuery(TbPreparedStatement.java:136)
at test.main(test.java:14)
SQL
복사
원인
•
DB Link SQL 재조립 시 '?' 문자 그대로 SQL을 생성하여 Oracle에서 해당 문자가 인식되지 않아 발생하였습니다.
•
Tibero 에서 JDBC 를 통해 수신하는 쿼리의 '?' 부분이 DB link를 통해 Oracle로 전송 되어 오류 발생하였습니다.
•
오류 발생 내용
$6 = 0x7fe2ac5fb980 "SELECT QB_004.\"C1\",QB_004.\"C2\" FROM \"T1\" QB_004 WHERE (QB_004.\"C2\" = ?)
AND (QB_004.\"C2\" IS NOT NULL) AND (QB_004.\"C2\" IS NOT NULL) AND (QB_004.\"C2\" = :0) "
→ 해당 부분에서 에러 발생
SQL
복사
해결
패치를 적용해 해결합니다. (적용 패치: FS07PS_333742a)
SQL 생성 시 '?' 문자를 ':Q' (바인드 변수 형식)으로 변경한 패치 적용 필요합니다.
SQL 처리 과정 자체에 변경사항이 필요하여 회피책은 별도로 존재하지 않습니다.
주의
티맥스티베로에서 제공하는 기술지원을 통해 패치를 적용합니다.