将图像从客户端电脑复制到 BLOB(又名 Oracle 中的 Java 函数)

发布于 2024-09-06 02:26:49 字数 2997 浏览 3 评论 0原文

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

I've been stuck with this for past two days. I've go java function stored in Oracle system which is supposed to copy image from local drive do remote database and store it in BLOB - it's called CopyBLOB and looks like this:

  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(  ) );
          }
      }
    }
}

The wrapper function is defined in package "MyPackage" as folows:

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

And the inserting function called image_add is as simple as this:

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

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

Now the problem: When I type

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

I get the ORA-29531 Error: No method copy in class CopyBLOB.
Can you help me, please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝眼泪 2024-09-13 02:26:49

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

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
(什么?)”

这可疑地接近 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;

The method in your class has this signature:

public static void copy(int ident, String path)

But in your Java Stored Procedure you have specified this signature:

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

I think if you change the first argument to java,lang.Integer your problem should resolve itself. You should probably change the datatype of the ID parameter in the IMAGE_ADDER() procedure as well.

edit

"Any ideas how to upload local files?"

Not unreasonably, the database can only interact with files which are visible to its server. Generally that limits matters to files and directories which are physically on the same box, unless the network admin has mapped some remote drives.

Transferring files from a local PC drive to a server is really a client i.e. application issue, it isn't the sort of thing the database should really get involved with.

I know that isn't what you were hoping to hear. If you really want to drive the file uploading from teh database, then the mechanism remains the same whenever we want to transfer files across a network: FTP. Tim Hall has published a PL/SQL implementation for FTP on his Oracle-Base site. Find out more.

"long as the file is smaler than 2000B
(WTF?)"

That is suspiciously close to the BINARY CHAR limit (2000). In older versions of Oracle we had to use a two-step process: insert a placeholder and then issue an update. Something like this:

  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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文