将图像从客户端 pc 又名 Oracle 中的 Java 函数复制到 BLOB

Posted

技术标签:

【中文标题】将图像从客户端 pc 又名 Oracle 中的 Java 函数复制到 BLOB【英文标题】:Copy image to BLOB from client pc aka Java function in Oracle 【发布时间】:2010-06-12 14:45:07 【问题描述】:

过去两天我一直被这个问题困扰。我已经将 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 类中没有方法复制。 你能帮帮我吗?

【问题讨论】:

【参考方案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 实现。 Find out more.

"只要文件小于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;

【讨论】:

你说得对——这是以前的工作遗留下来的,我没有注意到。谢谢你,但还有另一个问题:add_image 程序没有运行。我不知道为什么,甲骨文说交易成功,但没有任何反应。有任何想法吗?谢谢。 @mumich - 你怎么知道它没有运行?另外,为什么要取消设置然后设置 AutoCommit 模式? execute() 在 AutoCommit 关闭时发生。由于您没有明确的提交,是否有可能插入已运行但未保存? 它没有运行的原因是程序退出 b4 并出现 FileNotFoundException。这意味着问题解决了,但这是我没有得到的另一件事。来源来自互联网,我希望我可以为它提供本地文件的路径,例如。 d:\pic.jpg 并且该类将创建连接并将文件上传到服务器。这不会发生。当我提供它时,它会提供一个服务器路径,例如。 /home/pic.jpg 它可以工作(只要文件小于 2000B(WTF?))。我在 SQL Developer 下运行一切。任何想法如何上传本地文件?非常感谢您的时间和帮助。

以上是关于将图像从客户端 pc 又名 Oracle 中的 Java 函数复制到 BLOB的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 java 套接字将图像从 android studio 发送到 pc,filePath 返回 null

替换在客户端 PC 中打开的服务器中的 .net 应用程序

从 Mac 中的 ios 客户端调用 PC 中的 signalR 服务器

将 BLOB(图像)从 oracle 导入到 hive

佳能 SDK - 将图像下载到主机 PC

使用sql将图像从客户端发送到数据库