将图像从客户端电脑复制到 BLOB(又名 Oracle 中的 Java 函数)
过去两天我一直被这个问题困扰。我已经将 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的类中的方法具有以下签名:
但是在您的 Java 存储过程中,您指定了以下签名:
我认为如果您将第一个参数更改为
java,lang.Integer
您的问题应该会自行解决。您可能还应该更改 IMAGE_ADDER() 过程中 ID 参数的数据类型。编辑
数据库只能与其服务器可见的文件交互,这并非没有道理。一般来说,这限制了物理上位于同一机器上的文件和目录的问题,除非网络管理员映射了一些远程驱动器。
将文件从本地 PC 驱动器传输到服务器实际上是客户端(即应用程序)问题,这不是数据库真正应该参与的事情。
我知道这不是你希望听到的。如果您确实想驱动从数据库上传文件,那么每当我们想通过网络传输文件时,机制都保持不变:FTP。 Tim Hall 在他的 Oracle-Base 站点上发布了 FTP 的 PL/SQL 实现。 了解更多。
这可疑地接近 BINARY CHAR 限制(2000)。在旧版本的 Oracle 中,我们必须使用两步过程:插入占位符,然后发出更新。如下所示:
The method in your class has this signature:
But in your Java Stored Procedure you have specified this signature:
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
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.
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: