0

私は過去2日間これで立ち往生しています。ローカルドライブからイメージをコピーしてリモートデータベースに保存することになっているOracleシステムに保存されているJava関数を使用して、BLOBに保存します。これはCopyBLOBと呼ばれ、次のようになります。

  import java.sql.*;  
  import oracle.sql.*;
  import java.io.*;

public class CopyBLOB 
{
  static int id;
  static String  fileName = null;
  static Connection conn = null;  

  public CopyBLOB(int idz, String f) 
  {
    id       = idz;
    fileName   = f;
  }

   public static void copy(int ident, String path) throws SQLException, FileNotFoundException 
   {
       CopyBLOB cpB = new CopyBLOB(ident, path);
       cpB.getConnection();
       cpB.callUpdate(id, fileName);
   }

    public void getConnection() throws SQLException
    {    
     DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
     try 
     {     
       conn = DriverManager.getConnection("jdbc:oracle:thin:@oraserv.ms.mff.cuni.cz:1521:db", "xxx", "xxx");
     } 
     catch (SQLException sqlex) 
     {
         System.out.println("SQLException while getting db connection: "+sqlex);
         if (conn != null)  conn.close();
     } 
     catch (Exception ex) 
     {
         System.out.println("Exception while getting db connection: "+ex);
         if (conn != null) conn.close();
     }
    }

    public void callUpdate(int id, String file ) throws SQLException, FileNotFoundException 
    {
      CallableStatement cs = null;
      try 
      {  
        conn.setAutoCommit(false);
        File f = new File(file);
        FileInputStream fin = new FileInputStream(f);
        cs = (CallableStatement) conn.prepareCall( "begin add_image(?,?); end;" );
        cs.setInt(1, id );
        cs.setBinaryStream(2, fin, (int) f.length());
        cs.execute();
        conn.setAutoCommit(true);        
      } 
      catch ( SQLException sqlex ) 
      {
            System.out.println("SQLException in callUpdateUsingStream method of given status : " + sqlex.getMessage() );
      } 
      catch ( FileNotFoundException fnex ) 
      {
            System.out.println("FileNotFoundException in callUpdateUsingStream method of given status : " + fnex.getMessage() );
      } 
      finally 
      {
          try 
          {          
            if (cs != null)  cs.close();
            if (conn != null) conn.close();
          } 
          catch ( Exception ex ) 
          {
            System.out.println("Some exception in callUpdateUsingStream method of given status : " + ex.getMessage(  ) );
          }
      }
    }
}

ラッパー関数は、パッケージ「MyPackage」で次のように定義されています。

  procedure image_adder( id varchar2, path varchar2 )  
  AS
    language java name 'CopyBLOB.copy(java.lang.String, java.lang.String)';

そして、image_addと呼ばれる挿入関数はこれと同じくらい簡単です:

procedure add_image( id numeric(10), pic blob)
  AS 

  BEGIN
    insert into pictures values (seq_pic.nextval, id, pic);
  END add_image;

今問題:私がタイプするとき

call MyPackage.image_adder(1, 'd:\samples\img.jpg');

ORA-29531エラーが発生します:CopyBLOBクラスにメソッドコピーがありません。手伝ってくれませんか。

4

1 に答える 1

1

クラスのメソッドには次のシグネチャがあります。

public static void copy(int ident, String path)

ただし、Javaストアドプロシージャでは、次の署名を指定しています。

'CopyBLOB.copy(java.lang.String, java.lang.String)'

あなたがあなたの問題への最初の議論を変えるならば、私はあなたがjava,lang.Integerそれ自身を解決するべきだと思います。おそらく、IMAGE_ADDER()プロシージャでもIDパラメータのデータ型を変更する必要があります。

編集

「ローカルファイルをアップロードする方法について何かアイデアはありますか?」

不合理ではありませんが、データベースはサーバーに表示されているファイルとのみ対話できます。ネットワーク管理者がいくつかのリモートドライブをマップしていない限り、通常、これは物理的に同じボックス上にあるファイルとディレクトリに問題を制限します。

ローカルPCドライブからサーバーへのファイル転送は、実際にはクライアント、つまりアプリケーションの問題であり、データベースが実際に関与する必要のある種類のものではありません。

私はそれがあなたが聞きたいと思っていたものではないことを知っています。データベースからのファイルのアップロードを本当に促進したい場合は、ネットワークを介してファイルを転送するときはいつでもメカニズムは同じままです:FTP。Tim Hallは、彼のOracle-BaseサイトでFTPのPL/SQL実装を公開しています。 詳細をご覧ください

「ファイルが2000B(WTF?)よりも小さい限り」

これは、BINARY CHARの制限(2000)に疑わしいほど近づいています。古いバージョンのOracleでは、プレースホルダーを挿入してから更新を発行するという2段階のプロセスを使用する必要がありました。このようなもの:

  procedure add_image( id numeric(10), pic blob) 
  AS       
  BEGIN 
      insert into pictures 
          values (seq_pic.nextval, id, empty_blob()); 
      update pictures 
      set col_pic = pic
      where id = seq_pic.currval;
  END add_image;
于 2010-06-12T16:04:11.127 に答える