2013-04-22 7 views
2

Я пытаюсь создать исходный объект Java в базе данных оракула с помощью JDBC.Создание Java в базе данных Oracle с помощью JDBC

Источник Я хочу создать следующий:

create or replace and resolve java source named "BlobIO" as package dbjava; 


import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.io.*; 


public class BlobIO { 

    /** 
    * Stores a blob into a local file (or even UNC-path) 
    * @param blob The blob locator that should be stored in a file 
    * @param filename The filename to write to 
    * @param bufferSize The buffer size for data transfer 
    * @return 1 if successful, 0 if failed 
    */ 
    public static int blobToFile(java.sql.Blob blob, String filename, int bufferSize) 
    { 
     OutputStream os = null; 
     InputStream is = null; 
     boolean fail = true; 
     try { 

      is = blob.getBinaryStream(); 
      os = new FileOutputStream(filename); 
      int amountRead = 0; 
      byte[] buffer = new byte[bufferSize]; 
      while ((amountRead = is.read(buffer, 0, buffer.length)) != -1) { 
       os.write(buffer, 0, amountRead); 
      } 
      is.close(); 
      os.flush(); 
      os.close(); 
      fail = false; 
     } catch (IOException ex) { 
      new File(filename).delete(); 
      System.err.println("Could not store blob to file."); 
      System.err.println("File : " + filename); 
      System.err.println("Reason : " + ex.getClass().getName() + " : " + ex.getMessage()); 
      fail = true; 
     } catch (SQLException ex) { 
      new File(filename).delete(); 
      System.err.println("Could not store blob to file."); 
      System.err.println("File : " + filename); 
      System.err.println("Reason : " + ex.getClass().getName() + " : " + ex.getMessage()); 
      fail = true; 
     } finally { 
      try {is.close();} catch (Exception ex) {} 
      try {os.flush();} catch (Exception ex) {} 
      try {os.close();} catch (Exception ex) {} 
     } 
     return fail? 0:1; 
    } 

    /** 
    * Stores a blob into a local file (or even UNC-path) 
    * @param query The query that should select ONLY the blob field 
    * @param filename The filename to write to 
    * @param bufferSize The buffer size for data transfer 
    * @return 1 if successful, 0 if failed 
    */ 
    public static int blobToFile(String query, String filename, int bufferSize) { 
     try { 
      Connection conn = DriverManager.getConnection("jdbc:default:connection:"); 
      Statement stmt = conn.createStatement(); 
      ResultSet rset = stmt.executeQuery(query); 
      InputStream is; 


      if (rset.next()) 
      { 
       int ret = blobToFile(rset.getBlob(1), filename, bufferSize); 
       if (rset.next()) 
       { 
        new File(filename).delete(); 
        System.err.println("Could not store blob to file."); 
        System.err.println("Blob query : " + query); 
        System.err.println("File : " + filename); 
        System.err.println("Reason : too many rows"); 
        rset.close(); 
        stmt.close(); 
        return 0; 
       } else { 
        rset.close(); 
        stmt.close(); 
        return ret; 
       } 
      } else { 
       System.err.println("Could not store blob to file."); 
       System.err.println("Blob query : " + query); 
       System.err.println("File : " + filename); 
       System.err.println("Reason : no records retrieved by query"); 
       rset.close(); 
       stmt.close(); 
       return 0; 
      } 
     } catch (Exception e) { 
      System.err.println(e.getMessage()); 
      return 0; 
     } 

    } 

} 
/

Я попытался с CallableStatement помощью метода выполнения, и это дает мне error: "Missing IN/OUT parameters" Когда я пытаюсь использовать метод выполнения на обычном Statement объекте Я получаю сообщение об ошибке: "

Non supported SQL92 token at position: 262" 

кого-то есть идея, что я делаю неправильно не могу найти что-нибудь на Google либо

.

EDIT: Этот код, который я использую для выполнения сценария (String sql содержит сценарий, который вы видите выше, переменная conn является объектом Connection.

CallableStatement stat = conn.prepareCall(sql); 
stat.setEscapeProcessing(false); 
stat.execute(); 

Если я стараюсь только с Заявлением именно это:

Statement stat = conn.createStatement(); 
stat.execute(sql); 
+0

Не могли бы вы разместить полный код, который вы используете для создания объекта Java (а не только исходного кода этого объекта Java)? –

+0

@FrankSchmitt: Это полный код, это сценарий, который я пытаюсь выполнить, значит, вы имеете в виду код Java для JDBC? – Sonaryr

+0

@FrankSchmitt Я добавил эти 2 части. – Sonaryr

ответ

5

Итак, в итоге проблема возникла, она должна была быть CallableStatement с setEscapeProcessing(false).

+0

Ты мой спаситель. – Realn0whereman

2

Пожалуйста, пост полного тщательного примера. Ваш код работает, вот результат на моем 11.1.0.7.0 db. Сначала установка:

SQL> create or replace directory TMP as '/tmp'; 

Directory created 

SQL> CREATE TABLE testBlob (a BLOB); 

Table created 

SQL> INSERT INTO testBlob VALUES (utl_raw.cast_to_raw('StackOverflow')); 

1 row inserted 

Первая функция:

SQL> CREATE OR REPLACE FUNCTION blob2File(p_blob BLOB, 
    2          p_path VARCHAR2, 
    3          p_buffer NUMBER) 
    4 RETURN NUMBER AS 
    5 LANGUAGE JAVA NAME 
    6  'dbjava.BlobIO.blobToFile(java.sql.Blob, 
    7        java.lang.String, 
    8        int) return int'; 
    9/

Function created 

SQL> DECLARE 
    2  l_blob BLOB; 
    3  l_return INT; 
    4 BEGIN 
    5  SELECT * INTO l_blob FROM testBlob; 
    6  l_return := blob2File(l_blob, '/tmp/test.blob', 1024); 
    7  dbms_output.put_line(l_return); 
    8 END; 
    9/

1 

Для второй функции:

SQL> CREATE OR REPLACE FUNCTION queryBlob2File(p_query VARCHAR2, 
    2           p_path VARCHAR2, 
    3           p_buffer NUMBER) RETURN NUMBER AS 
    4 LANGUAGE JAVA NAME 
    5  'dbjava.BlobIO.blobToFile(java.lang.String, 
    6        java.lang.String, 
    7        int) return int'; 
    8/

Function created 

SQL> DECLARE 
    2  l_query VARCHAR2(1000); 
    3  l_return INT; 
    4 BEGIN 
    5  l_query := 'SELECT * FROM testBlob'; 
    6  l_return := queryBlob2File(l_query, '/tmp/test.blob', 1024); 
    7  dbms_output.put_line(l_return); 
    8 END; 
    9/

1 

PL/SQL procedure successfully completed 

Вы можете использовать UTL_FILE пакет, чтобы иметь дело с файлами непосредственно в PL/SQL:

SQL> DECLARE 
    2  l_file utl_file.file_type; 
    3  l_line VARCHAR2(1024); 
    4 BEGIN 
    5  l_file := utl_file.fopen(location => 'TMP', 
    6        filename => 'test.blob', 
    7        open_mode => 'R'); 
    8  utl_file.get_line(l_file, l_line); 
    9  dbms_output.put_line(l_line); 
10  utl_file.fclose(l_file); 
11 END; 
12/

StackOverflow 
+1

Я знаю, что мой код работает, когда я запускаю скрипт, используя sqlplus, он создается, но не тогда, когда я запускаю скрипт с помощью JDBC. – Sonaryr

+0

Как вы называете источник java базы данных из 'jdbc'? Пожалуйста, отправьте пример ** THOROUGH **. Я показал вам, как вы можете назвать это из PL/SQL. Поскольку вы можете вызвать PL/SQL-скрипты из 'jdbc', я не вижу, где проблема! –

+0

Я сказал в своем начале сообщение, я поместил весь скрипт в переменную java 'String' и создаю' CallableStatement' или 'Statement', чтобы выполнить его через JDBC. Я не хочу вызывать «источник Java» с помощью JDBC, я хочу создать его с помощью JDBC. – Sonaryr

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