0

我正在编写一段代码来对 XML 数据应用非常特定于客户的编码。起初我尝试只使用 PL-SQL 来执行此操作,但性能非常差(160 条记录需要 1 小时)。之后我只用 java 尝试了它,它提供了很好的性能(1 分钟内有 400.000 条记录)

现在我想看看当我用 Java 构建代码并将其加载到数据库中时性能如何。

为此,我有以下代码:

create or replace and compile java source named XmlNumericEncoder as
public class XmlNumericEncoder {
    public static String encode(String xmlstring) { 
        String xmlstring_out = "";
        for (int i = 0; i < xmlstring.length(); i++){
            char ch = xmlstring.charAt(i);        

            if ((int)ch  >=  192 && (int)ch <= 255){
               xmlstring_out += "&#" + (int)ch + ";"; 
            } else {
               xmlstring_out += ch;
            }
        }
        return xmlstring_out;
    } 
}



CREATE OR REPLACE FUNCTION XmlNumericEncoder(xmlstring varchar2)
        RETURN String
        AS LANGUAGE JAVA
        NAME 'XmlNumericEncoder.encode(java.lang.String) return java.lang.String';

这段代码可以通过以下方式执行:

select XmlNumericEncoder('Böhmer') from dual;

我现在面临的问题是我需要该函数在存储在 clob 中的大部分数据上执行。我知道有一个 java.sql.Clob 类,我可以让它作为输入参数工作,但我似乎无法让它作为输出参数工作,我一直遇到空指针异常。

这是我正在使用的代码:

import java.sql.Clob;
import java.sql.SQLException;

public class XmlNumericEncoder {
    public static Clob encode(Clob xmlclob) throws SQLException { 
        String xmlstring_out = "";
        Clob xmlclob_out = null;
        for (int i = 0; i < xmlclob.length(); i++){
            char ch = xmlclob.getSubString(i,1).charAt(1);        

            if ((int)ch  >=  192 && (int)ch <= 255){
               xmlstring_out += "&#" + (int)ch + ";"; 
            } else {
               xmlstring_out += ch;
            }
        }
        int setString = xmlclob_out.setString(0, xmlstring_out);

        return xmlclob_out;
    } 

有什么想法我哪里出错了吗?

4

5 回答 5

2

与您的问题类似,我需要从数据库中运行的 Java 程序将 clob 插入 Oracle 数据库。这里没有一个答案对我有用。

我最终找到了解决方案,诀窍是使用 oracle.sql.CLOB

这是我发现的方法:

create table test_clob (
    c clob
);

create or replace and compile java source named java_clob_insert as

import java.sql.Connection;
import java.sql.PreparedStatement;
import oracle.sql.CLOB;
import java.io.Writer;

public class JavaClobInsert {

    public static void doInsert () {

        try {

            //create the connection and statement
            Connection oracleConn =
                (new oracle.jdbc.OracleDriver()).defaultConnection();

            String stmt = "INSERT INTO test_clob values (?)";

            PreparedStatement oraclePstmt = oracleConn.prepareStatement(stmt);

            //Imagine we have a mysql longtext or some very long string
            String s = "";
            for (int i = 0; i < 32768; i++) {
                s += i % 10;
            }

            //Initialise the Oracle CLOB
            CLOB clob;
            clob = CLOB.createTemporary(oracleConn, true, CLOB.DURATION_CALL);

            //Good idea to check the string is not null before writing to clob
            if (s != null) {
                Writer w = clob.setCharacterStream( 1L );
                w.write(s);
                w.close();
                oraclePstmt.setClob(1, clob);
            } else {
                oraclePstmt.setString(1, "");
            }

            //clean up
            oraclePstmt.executeUpdate();
            oracleConn.commit();
            oraclePstmt.close();
            oracleConn.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/

create or replace procedure clob_insert as language java name 
    'JavaClobInsert.doInsert()';    
/

begin
    clob_insert;
end;
/

select *
from   test_clob; 
于 2015-09-07T01:24:08.810 回答
0

好的,我已经尝试过了,但这似乎不是 java 代码实际存储在 Oracle 数据库中的方式。我已将代码修改为:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED MAGMA."XMLNUMERICENCODER" AS
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class XmlNumericEncoder {

public static Clob encode(Clob xmlstring) throws SQLException { 

    Connection conn = DriverManager.getConnection("jdbc:default:connection:");

    String xmlstring_out = "";
    Clob xmlclob_out = conn.createClob();
    for (int i = 0; i < xmlstring.length(); i++){
        char ch = xmlstring.getSubString(i,1).charAt(1);        
        if ((int)ch  >=  192 && (int)ch <= 255){
           xmlstring_out += "&#" + (int)ch + ";"; 
        } else {
           xmlstring_out += ch;
        }
    }
    int setString = xmlclob_out.setString(0, xmlstring_out);

    return xmlclob_out;
} 

}

但是当我尝试编译它时,我收到以下错误:

XMLNUMERICENCODER:12: 找不到符号

符号:方法 createClob()

位置:接口 java.sql.Connection

Clob xmlclob_out = conn.createClob();

我也尝试过像这样创建连接: Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@//localhost:1521/dbname", "username", "password")

但这给了我同样的错误。

对我来说,我需要创建一个连接似乎有点奇怪,因为我已经在数据库中了。

于 2013-10-03T06:59:06.693 回答
0

您首先需要获得 JDBC 连接。在 Java 存储过程中,您应该这样做:

Connection conn = DriverManager.getConnection("jdbc:default:connection:");

您可以使用 的createClob()方法java.sql.Connection来实例化一个对象来表示您的 CLOB。

请参阅Clob 的 API 文档

于 2013-09-30T15:02:31.413 回答
0

NullpointerException 是由于该行

Clob xmlclob_out = null;

在这种情况下,我真的不知道如何初始化 Clob。在使用连接的教程中,您可以执行类似的操作

Clob myClob = this.con.createClob();
于 2013-09-30T14:34:31.227 回答
0

我知道这是一个旧帖子,但是..

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "MyJava"
as 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import oracle.sql.BLOB;
import oracle.sql.CLOB;

public class MyJava{
    public static CLOB myClob() {
        try {
            String outputString = "this is my text to write in the CLOB";
            Connection conn = DriverManager.getConnection("jdbc:default:connection:");
            CLOB clob = CLOB.createTemporary(conn, false, BLOB.DURATION_SESSION);
            clob.setString(1L, outputString);
            return clob;
        } catch (SQLException ex) {
            return null;
        }
    }
}
/

然后是 PL/SQL 的包装器

CREATE OR REPLACE FUNCTION MY_JAVA_CLOB() RETURN clob
AS language java
 name 'MyJava.myClob() return oracle.sql.CLOB';
/
于 2019-09-12T11:32:11.507 回答