是否有从 oracle 结果集中检索二进制 XML 的函数

Is there an function to retrieve the binary XML from oracle result set

我正在尝试从 Oracle 12C 数据库的 XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS SECUREFILE BINARY XML 中提取数据。

我在我的代码中使用这个 select 查询:

select xmlserialize(document a.xmlrecord as clob) as xmlrecord from tablename

ResultSet rset = stmt.executeQuery();

OracleResultSet orset = (OracleResultSet) rset;
while (orset.next()) {
oracle.sql.CLOB xmlrecord = (oracle.sql.CLOB) orset.getClob(1);
Reader reader = new BufferedReader(xmlrecord.getCharacterStream()); 
}

此处“orset.getClob”在 oracle DB 中占用了更多内存,我们正在用完 oracle 数据库中的进程内存。目前我们有 XML 类型的存储作为 CLOB,业务有兴趣将其更改为 BINARY XML。

是否有任何选项可以从 oracle 结果集中检索二进制 XML?

请注意,我已经尝试过“orset.getClob”,这会导致内存错误,因为它正在将二进制 XML 更改为 clob。

也尝试过使用“XMLType xml = (XMLType) orset.getObject(1);”,这工作正常,但是获取 100 万条 XML 条记录需要 27 分钟。

而如果 table 类型存储是 CLOB 而不是 BINARY XML,同样的 100 万次在 5 分钟内完成。

是否有任何其他选项来检索二进制 XML?

Using JDBC to Access XML Documents in Oracle XML DB 的 Oracle 文档指出:

You can select XMLType data using JDBC in any of these ways:

  • Use SQL/XML function XMLSerialize in SQL, and obtain the result as an oracle.sql.CLOB, java.lang.String or oracle.sql.BLOB in Java. The Java snippet in Example 13-2 illustrates this.
  • Call method getObject() in the PreparedStatement to obtain the whole XMLType instance. The return value of this method is of type oracle.xdb.XMLType. Then you can use Java functions on class XMLType to access the data. Example 13-3 shows how to do this.

所以你应该可以在SQL中使用XMLSERIALIZE( DOCUMENT your_binary_xml_column AS BLOB ),然后使用OracleResultSet#getBLOB(int)来获取二进制数据。

解释 Oracle 的 Example 13-2 以转换为 BLOB 而不是 CLOB:

DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:oci8:@", "QUINE", "CURRY");
OraclePreparedStatement stmt = (OraclePreparedStatement) conn.prepareStatement(
     "SELECT XMLSerialize(DOCUMENT e.poDoc AS BLOB) poDoc FROM po_xml_tab e");
ResultSet rset = stmt.executeQuery();
OracleResultSet orset = (OracleResultSet) rset;
while(orset.next())
{
  // the first argument is a BLOB
  oracle.sql.BLOB clb = orset.getBLOB(1);
  // now use the BLOB inside the program
}