繁体   English   中英

从Oracle中的客户端PC又称为Java函数将图像复制到BLOB

[英]Copy image to BLOB from client pc aka Java function in Oracle

我已经坚持了两天了。 我已经将Java函数存储在Oracle系统中,该函数应该从本地驱动器复制映像并做远程数据库,并将其存储在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中没有方法复制。 你能帮我吗?

您的类中的方法具有以下签名:

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中,我们必须使用两步过程:插入一个占位符,然后发布更新。 像这样:

  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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM