2015-12-11 4 views
0

Я пытаюсь создать функцию в базе данных Oracle, которая использует класс JAVA для чтения файлов с сетевого диска и возвращает содержимое файла в виде BLOB.читать сетевой файл из базы данных Oracle с помощью JAVA

До сих пор здесь прогресс

JAVA-код - FileAPI.java

import java.lang.*; 
import java.io.*; 
import java.sql.*; 

public class FileAPI 
{ 
    public static String readFile (String path, Blob[] outLob) 
    { 
    FileInputStream fileStream = null; 
    try {  
     fileStream = new FileInputStream(path); 

     byte[] buffer = new byte[100]; 
     int i = 0; 
     /* for testing just read 100 bytes */ 
     /* code required for reading full file */ 
     i = fileStream.read(buffer, 1, 100);   
     outLob[0] = new javax.sql.rowset.serial.SerialBlob(buffer); 

     if(fileStream != null) 
       fileStream.close();   

     return "success"; 
     } 
    catch (Exception e) {  
     return e.getMessage(); 
     } 
    } 
}; 

функции Oracle PL/SQL

CREATE OR REPLACE FUNCTION readFile (p_path IN VARCHAR2, p_outlob IN OUT NOCOPY BLOB) 
RETURN VARCHAR2 
AS LANGUAGE JAVA 
NAME 'FileAPI.readFile(
     java.lang.String, 
     java.sql.Blob[]) return java.lang.String'; 

PL/SQL анонимный блок для тестирования выше функции

SET SERVEROUTPUT ON; 
DECLARE 
    l_temp BLOB; 
    l_res VARCHAR2(1000); 
BEGIN 
    l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp); 
    IF l_res = 'success' 
    THEN 
     DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp)); 
    ELSE 
     DBMS_OUTPUT.PUT_LINE('Error info '|| l_res); 
    END IF; 
END; 
/

Когда я бегу над блоком, тогда я не получаю никакой информации об ошибке. Это просто печать «Информация об ошибке». Никакие подробные исключения не печатаются.

Возможно, кто-то подскажет, что здесь происходит.

Также вы можете предложить прочитать содержимое полного файла и добавить его в переменную BLOB (outLob [0]) в JAVA?

детали JAVA

Java версия "1.7.0_79" Java (TM) SE Runtime Environment (сборка 1.7.0_79-b15) Java HotSpot (TM) 64-разрядного сервера VM (сборка 24,79-B02, смешанный режим)

Oracle DB - Oracle 11g R2 EE

С наилучшими пожеланиями,

[обновлено JAVA код]

import java.lang.*; 
import java.io.*; 
import java.sql.*; 

public class FileAPI 
{ 
    public static String readFile (String path, Blob[] outLob) 
    { 
    FileInputStream fileStream = null; 
    Blob tmp = outLob[0]; 
    try {  
     fileStream = new FileInputStream(path); 

     byte[] buffer = new byte[100]; 
     int i = 0; 
     /* for testing just read 100 bytes */ 
     /* code required for reading full file */ 
     i = fileStream.read(buffer, 0, 100);   
     tmp = new javax.sql.rowset.serial.SerialBlob(buffer); 
     outLob[0] = tmp; 

     if(fileStream != null) 
       fileStream.close();   

     return "success"; 
     } 
    catch (Exception e) {  
     //return e.getMessage(); 
     return e.toString(); 
     } 
    } 
}; 
+0

Попробуйте 'e.toString()' вместо 'e.getMessage()'. Есть определенные случаи, когда сообщение об ошибке пусто. – Timekiller

+0

Спасибо за ответ. Была проблема с массивом. Я исправил это. Теперь, когда я запускаю блок pl/sql, я становлюсь ниже ошибки ORA-00932: непоследовательные типы данных: ожидается, что аргумент OUT в позиции 2, являющийся экземпляром определенного класса Java, конвертируемого в тип Oracle, получил объект, который не мог быть преобразованным –

+0

Какое правильное сопоставление данных для Oracle datatype BLOB в JAVA? или мне нужно изменить код JAVA? –

ответ

1

Чтобы создать Blob непосредственно с Java, вам нужно будет получить доступ к объекту Connection и сообщить базе данных для создания пробела через него; затем получить выходной поток объекта blob и написать ему.

import oracle.jdbc.OracleDriver; 

import oracle.sql.BLOB; 

import java.io.FileInputStream; 
import java.io.OutputStream; 

import java.sql.Blob; 
import java.sql.Connection; 
import java.sql.DriverManager; 

public class FileAPI 
{ 
    public static String readFile(String path, Blob[] outLob) 
    { 
     try 
     { 
      DriverManager.registerDriver(new OracleDriver()); 
      Connection conn = DriverManager.getConnection("jdbc:default:connection:"); 
      FileInputStream fileStream = null; 
      fileStream = new FileInputStream(path); 

      outLob[0] = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION); 
      OutputStream BlobOS = outLob[0].setBinaryStream(0); 
      byte[] buffer = new byte[100]; 

      int len = fileStream.read(buffer, 0, 100); 
      while (len > -1) 
      { 
       BlobOS.write(buffer, 0, len); 
       len = fileStream.read(buffer, 0, 100); 
      } 
      BlobOS.close(); 
      fileStream.close(); 

      return "success"; 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      return e.toString(); 
     } 
    } 
} 

Для этого вам необходимо включить Oracle JDBC для компиляции. BLOB.createTemporary() работает даже с Java 1.4.2 (oracle 10); начиная с 1.6, есть функция createBlob в sql.Connection, которая должна делать то же самое.

Кроме того, это немного не имеет отношения к вашему вопросу, но обратите внимание, что вы можете прочитать стандартный вывод (System.out и System.err) хранимых процедур Java в журналах udump на сервере базы данных, поэтому не стесняйтесь использовать e.printStackTrace() - это очень помогает отладке.

+0

Большое спасибо! В то время как я пробовал другой подход, и он работает нормально. Я отправлю его в ближайшее время здесь –

0

JAVA код

import java.lang.*; 
import java.io.*; 
import java.sql.Blob; 

public class FileAPI { 
    public static String readFile(String path, Blob[] outLob) { 
     FileInputStream fileStream = null; 
     Blob tmp = outLob[0]; 
     OutputStream ous = null; 
     try { 
      ous = tmp.setBinaryStream(1); 
      fileStream = new FileInputStream(path); 
      //System.out.println("fileStream:" + fileStream);   
      byte[] buffer = new byte[4096]; 
      int read = 0; 
      while ((read = fileStream.read(buffer)) != -1) { 
       ous.write(buffer, 0, read); 
      } 
      outLob[0] = tmp;    
     } catch (Exception e) { 
      return e.toString(); 
      //System.out.println(e.toString()); 
     } finally { 
      try { 
       if (fileStream != null) fileStream.close(); 
       if (ous != null) ous.close(); 
      } catch (IOException e) {} 
     } 
     return "success"; 
    } 
} 

Oracle Функция

Анонимный блок для тестирования

SET SERVEROUTPUT ON; 
DECLARE 
    l_temp BLOB; 
    l_res VARCHAR2(1000); 
BEGIN 
    -- important, this is required so that LOB pointer is passed to JAVA 
    DBMS_LOB.CREATETEMPORARY(l_temp,TRUE); 
    l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp); 
    IF l_temp IS NOT NULL 
    THEN 
     DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp)); 
    ELSE 
     DBMS_OUTPUT.PUT_LINE('Error info '|| l_res); 
    END IF; 
    DBMS_LOB.FREETEMPORARY(l_temp); 
END; 
/

Примечание: требуется права доступа должны быть предоставлены пользователю Oracle с помощью dbms_java.grant_permission API. Пользователь сервера (пользователь, работающий с Oracle) должен иметь доступ к доступу к сети.

Смежные вопросы