将Oracle CLOB从Java传递到Java

将Oracle CLOB从Java传递到Java,java,sql,oracle,plsql,clob,Java,Sql,Oracle,Plsql,Clob,我正在编写一段代码,将特定于客户的编码应用于XML数据。起初,我试图只使用PL-SQL来实现这一点,但性能非常差(160条记录需要1小时)。在那之后,我只使用java进行了尝试,wich的性能非常好(1分钟内录制了400.000条记录) 现在,我想看看用Java构建代码并将其加载到数据库中时的性能如何 为此,我有以下代码: create or replace and compile java source named XmlNumericEncoder as public class XmlNu

我正在编写一段代码,将特定于客户的编码应用于XML数据。起初,我试图只使用PL-SQL来实现这一点,但性能非常差(160条记录需要1小时)。在那之后,我只使用java进行了尝试,wich的性能非常好(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';
我现在面临的问题是,我需要函数在CLOB中存储的大部分数据上执行。我知道有一个java.sql.Clob类,我可以让它作为输入参数工作,但我似乎无法让它作为输出参数工作,我一直遇到nullpointer异常

这是我使用的代码:

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;
    } 
导入java.sql.Clob;
导入java.sql.SQLException;
公共类XmlNumericEncoder{
公共静态Clob编码(Clob xmlclob)抛出SQLException{
字符串xmlstring_out=“”;
Clob xmlclob_out=null;
对于(int i=0;i如果((int)ch>=192&(int)ch,则NullpointerException是由于该行引起的

Clob xmlclob_out = null;
在这种情况下,我真的不知道如何初始化Clob

Clob myClob = this.con.createClob();

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

Connection conn = DriverManager.getConnection("jdbc:default:connection:");
您可以使用
java.sql.Connection
createClob()
方法来实例化一个对象来表示CLOB


请参阅。

好的,我已经尝试过了,但当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;
} 
创建或替换并解析名为MAGMA的JAVA源代码。“XMLNUMERICENCODER”作为
导入java.sql.Clob;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.SQLException;
公共类XmlNumericEncoder{
公共静态Clob编码(Clob xmlstring)引发SQLException{
Connection conn=DriverManager.getConnection(“jdbc:default:Connection:”);
字符串xmlstring_out=“”;
Clob xmlclob_out=conn.createClob();
对于(int i=0;i如果((int)ch>=192&(int)ch与您的问题类似,我需要从数据库中运行的Java程序向Oracle数据库中插入clob。这里的答案对我来说都不太合适

我最终找到了解决方案,诀窍是使用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; 
create table test\u clob(
克洛布
);
创建或替换并编译名为java_clob_insert as的java源代码
导入java.sql.Connection;
导入java.sql.PreparedStatement;
导入oracle.sql.CLOB;
导入java.io.Writer;
公共类JavaClobInsert{
公共静态void doInsert(){
试一试{
//创建连接和语句
连接oracleConn=
(新的oracle.jdbc.OracleDriver()).defaultConnection();
字符串stmt=“插入测试_clob值(?);
PreparedStatement oraclePstmt=oracleConn.prepareStatement(stmt);
//假设我们有一个mysql长文本或一些很长的字符串
字符串s=“”;
对于(int i=0;i<32768;i++){
s+=i%10;
}
//初始化Oracle CLOB
CLOB-CLOB;
clob=clob.createTemporary(oracleConn,true,clob.DURATION\u调用);
//在写入clob之前检查字符串不为null是个好主意
如果(s!=null){
Writer w=clob.setCharacterStream(1L);
w、 书写;
w、 close();
oraclePstmt.setClob(1,clob);
}否则{
oraclePstmt.setString(1,“”);
}
//清理
oraclePstmt.executeUpdate();
oracleConn.commit();
oraclePstmt.close();
oracleConn.close();
}捕获(例外e){
e、 printStackTrace();
}
}
}
/
创建或替换过程clob_insert作为语言java名称
'JavaClobInsert.doInsert()';
/
开始
clob_插件;
结束;
/
挑选*
来自test_clob;

我知道这是一篇老文章,但是

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';
/

你从哪里得到空指针异常?你能发布你的堆栈跟踪吗?似乎很明显你得到了空指针异常:
Clob xmlclob_out=null;
,你从来没有在代码中实例化过任何Clob对象。我知道,但应该怎么做?“java.sql.Clob是抽象的;无法实例化”,我应该从oracle发送输入和输出clob吗?如果添加一层java可以提高性能,那么PL/SQL代码中一定有错误。在我测试的两个实例(9ir2和11gr2)上,用PL/SQL重写的相同函数速度更快。在使用PL/SQL优化的11gr2中,结果是PL/SQL的100倍。以下是我的设置:
CREATE OR REPLACE FUNCTION MY_JAVA_CLOB() RETURN clob
AS language java
 name 'MyJava.myClob() return oracle.sql.CLOB';
/