2013-09-30 2 views
0

Я пишу фрагмент кода, чтобы применить кодировку с конкретным клиентом к XML-данным. Сначала я попытался сделать это, используя только PL-SQL, но столкнулся с очень низкой производительностью (1 час для 160 записей). После этого я попробовал его только с java, который дал отличную производительность (400 000 записей за 1 минуту)Пропустить Oracle clobs от и до Java

Теперь я хочу посмотреть, как работает производительность, когда я создаю код на 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; 

Проблема Я сейчас облицовкой, что мне нужно, чтобы выполнить функцию на больших частях данных, хранящихся в клобах. Я знаю, что есть класс 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; 
    } 

Любые идеи, где я неправильно?

+0

Где вы получаете нулевые исключения указателя? Не могли бы вы разместить трассировку стека? –

+0

Кажется очевидным, что вы получаете исключение nullpointer: 'Clob xmlclob_out = null;', вы никогда не создаете экземпляр объекта Clob в своем коде. –

+0

Я знаю, но как это должно быть сделано? «java.sql.Clob - абстрактный, не может быть экземпляр», должен ли я посылать входной и выходной clob из oracle? – ErikL

ответ

0

NullPointerException из-за линии

Clob xmlclob_out = null; 

Я действительно не знаю, как инициализировать CLOB в этом случае. В a tutorial вы используете соединение, вы делаете что-то вроде

Clob myClob = this.con.createClob(); 
0

в первую очередь необходимо, чтобы заполучить соединение JDBC. Изнутри хранимой процедуры Java, вы должны сделать это следующим образом:

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

вы можете использовать createClob() метод java.sql.Connection для создания экземпляра объекта, чтобы представить свой CLOB.

См. The API documentation of Clob.

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")

, но это дало мне ту же ошибку.

Мне кажется немного странным, что мне нужно создать соединения, так как я уже в базе данных.

2

Как и ваша проблема, у меня было требование вставить клоб в базу данных Oracle из программы Java, работающей в базе данных. Ни один из ответов здесь не сработал для меня.

В конце концов я нашел решение, трюк в том, чтобы использовать 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; 
Смежные вопросы