我正在尝试在Oracle数据库中创建一个函数,该函数使用JAVA类从网络驱动器读取文件并将文件内容作为BLOB返回。
直到现在,这是进展
JAVA代码 - FileAPI.java
import java.lang.*;
import java.io.*;
import java.sql.*;
public class FileAPI
{
public static String readFile (String path, Blob[] outLob)
{
FileInputStream fileStream = null;
try {
fileStream = new FileInputStream(path);
byte[] buffer = new byte[100];
int i = 0;
/* for testing just read 100 bytes */
/* code required for reading full file */
i = fileStream.read(buffer, 1, 100);
outLob[0] = new javax.sql.rowset.serial.SerialBlob(buffer);
if(fileStream != null)
fileStream.close();
return "success";
}
catch (Exception e) {
return e.getMessage();
}
}
};
Oracle PL / SQL函数
CREATE OR REPLACE FUNCTION readFile (p_path IN VARCHAR2, p_outlob IN OUT NOCOPY BLOB)
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'FileAPI.readFile(
java.lang.String,
java.sql.Blob[]) return java.lang.String';
PL / SQL匿名块来测试上面的函数
SET SERVEROUTPUT ON;
DECLARE
l_temp BLOB;
l_res VARCHAR2(1000);
BEGIN
l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp);
IF l_res = 'success'
THEN
DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp));
ELSE
DBMS_OUTPUT.PUT_LINE('Error info '|| l_res);
END IF;
END;
/
当我在阻止上面运行时,我没有收到任何错误信息。它只是打印“错误信息”。没有详细的例外情况。
有些人可以说明这里出了什么问题。
您还可以建议阅读完整文件的内容并将其附加到JAVA中的BLOB变量(outLob [0])吗?
JAVA详细信息
java版“1.7.0_79” Java(TM)SE运行时环境(版本1.7.0_79-b15) Java HotSpot(TM)64位服务器VM(内置24.79-b02,混合模式)
Oracle DB - Oracle 11g r2 EE
最诚挚的问候,
[更新JAVA代码]
import java.lang.*;
import java.io.*;
import java.sql.*;
public class FileAPI
{
public static String readFile (String path, Blob[] outLob)
{
FileInputStream fileStream = null;
Blob tmp = outLob[0];
try {
fileStream = new FileInputStream(path);
byte[] buffer = new byte[100];
int i = 0;
/* for testing just read 100 bytes */
/* code required for reading full file */
i = fileStream.read(buffer, 0, 100);
tmp = new javax.sql.rowset.serial.SerialBlob(buffer);
outLob[0] = tmp;
if(fileStream != null)
fileStream.close();
return "success";
}
catch (Exception e) {
//return e.getMessage();
return e.toString();
}
}
};
答案 0 :(得分:1)
要直接从Java创建Blob,您必须访问Connection对象并告诉数据库通过它创建blob;然后获取blob对象的输出流并写入它。
import oracle.jdbc.OracleDriver;
import oracle.sql.BLOB;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
public class FileAPI
{
public static String readFile(String path, Blob[] outLob)
{
try
{
DriverManager.registerDriver(new OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
FileInputStream fileStream = null;
fileStream = new FileInputStream(path);
outLob[0] = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
OutputStream BlobOS = outLob[0].setBinaryStream(0);
byte[] buffer = new byte[100];
int len = fileStream.read(buffer, 0, 100);
while (len > -1)
{
BlobOS.write(buffer, 0, len);
len = fileStream.read(buffer, 0, 100);
}
BlobOS.close();
fileStream.close();
return "success";
}
catch (Exception e)
{
e.printStackTrace();
return e.toString();
}
}
}
您需要包含Oracle JDBC才能进行编译。 BLOB.createTemporary()
甚至适用于Java 1.4.2(oracle 10);从1.6开始,在sql.Connection中有createBlob
函数,它也应该这样做。
此外,这与您的问题有点无关,但请注意您可以在数据库服务器上的udump
日志中读取Java存储过程的标准输出(System.out和System.err),因此不要犹豫使用e.printStackTrace()
- 这有助于极大地调试。
答案 1 :(得分:0)
JAVA代码
import java.lang.*;
import java.io.*;
import java.sql.Blob;
public class FileAPI {
public static String readFile(String path, Blob[] outLob) {
FileInputStream fileStream = null;
Blob tmp = outLob[0];
OutputStream ous = null;
try {
ous = tmp.setBinaryStream(1);
fileStream = new FileInputStream(path);
//System.out.println("fileStream:" + fileStream);
byte[] buffer = new byte[4096];
int read = 0;
while ((read = fileStream.read(buffer)) != -1) {
ous.write(buffer, 0, read);
}
outLob[0] = tmp;
} catch (Exception e) {
return e.toString();
//System.out.println(e.toString());
} finally {
try {
if (fileStream != null) fileStream.close();
if (ous != null) ous.close();
} catch (IOException e) {}
}
return "success";
}
}
Oracle功能
CREATE OR REPLACE FUNCTION readFile (p_path IN VARCHAR2
, p_outlob IN OUT NOCOPY BLOB
)
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'FileAPI.readFile(
java.lang.String,
java.sql.Blob[]) return java.lang.String';
用于测试的匿名阻止
SET SERVEROUTPUT ON;
DECLARE
l_temp BLOB;
l_res VARCHAR2(1000);
BEGIN
-- important, this is required so that LOB pointer is passed to JAVA
DBMS_LOB.CREATETEMPORARY(l_temp,TRUE);
l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp);
IF l_temp IS NOT NULL
THEN
DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp));
ELSE
DBMS_OUTPUT.PUT_LINE('Error info '|| l_res);
END IF;
DBMS_LOB.FREETEMPORARY(l_temp);
END;
/
注意:应使用dbms_java.grant_permission API向Oracle用户提供所需的访问权限。服务器用户(运行Oracle的用户)应具有对网络共享的读访问权。