这是我第一次在 stackoverflow 中发帖提问, 我需要编写一个 java 存储过程来创建一个 excel 文件并返回一个包含文件数据(以字节为单位)的 blob。
我的pl/sql函数是下面的形式
function test_create_excel(i_username IN varchar2) return BLOB
AS LANGUAGE JAVA NAME 'NTO.Excel.ExcelFunctions.PushToExcel( java.lang.String ) return java.sql.Blob';
我的Java方法如下
public static java.sql.Blob TestPushToExcel(String username) throws IOException, SQLException{
//create excel file, read content to byte array and set to a blob
}
我的问题是我找不到任何方法来创建 java.sql.Blob 的实例,以便我可以使用 blob.setBinaryStream(..) 方法写入文件数据字节数组。
我尝试使用SerialBlob 实现,但它导致以下 oracle 错误
ORA-00932: inconsistent datatypes: expected a return value that is an instance of a user defined Java class convertible to an Oracle type got an object that could not be converted
有没有人遇到过这个问题,如果遇到过,您能分享一下您是如何解决的吗?
提前致谢。
编辑 Java
public static oracle.sql.BLOB getBlob(byte[] data) throws SQLException, IOException{
oracle.jdbc.OracleConnection conn = (oracle.jdbc.OracleConnection)new OracleDriver().defaultConnection();
oracle.sql.BLOB retBlob = oracle.sql.BLOB.createTemporary(conn, true, oracle.sql.BLOB.DURATION_SESSION);
java.io.OutputStream outStr = retBlob.setBinaryStream(0);
outStr.write(data);
outStr.flush();
return retBlob;
}
public static ExcelFileStore PushToExcel(String userId) throws IOException, SQLException{
ExcelFileStore fileStore = new ExcelFileStore();
fileStore.NU_USERID = userId;
fileStore.CreatedTime = new java.sql.Date(new Date().getTime());
fileStore.Last_Updated = new java.sql.Date(new Date().getTime());
fileStore.FileSize = fileData.length;
fileStore.FileData = getBlob(fileData);
return fileStore;
}
PL/SQL
function test_create_excel(i_username IN varchar2) return EXCELFILESTORE AS LANGUAGE JAVA NAME 'NTO.Excel.ExcelFunctions.PushToExcel( java.lang.String, ) return OracleObjects.ExcelFileStore';
OracleObject.ExcelfileStore是一个实现java.sql.SqlData的类,EXCELFILESTORE是oracle中的一个UDT。
我加载了引用 jar 和使用“sys.dbms_java.loadjava”为我的代码创建的 jar
我希望你能理解我的问题,因为我对 pl/sql 编程还很陌生
最佳答案
我错了。 可以完成。我花了一些时间让它工作,但最后,这是一个工作示例:
Java类
import oracle.jdbc.driver.*;
public class TestBlob {
public static oracle.sql.BLOB getBlob(String username) throws Exception {
oracle.jdbc.OracleConnection conn =
(oracle.jdbc.OracleConnection)new OracleDriver().defaultConnection();
oracle.sql.BLOB retBlob =
oracle.sql.BLOB.createTemporary(conn,
true,
oracle.sql.BLOB.DURATION_SESSION);
java.io.OutputStream outStr = retBlob.setBinaryStream(0);
outStr.write(username.getBytes());
outStr.flush();
return retBlob;
}
}
如您所见,我使用了 oracle.sql.BLOB
作为结果。我使用 BLOB
类的静态 createTemporary
方法创建它,指定它应该在 session 期间创建(oracle.sql.BLOB.DURATION_SESSION
参数)。
然后,我获取OutputStream
并写入数据。需要冲洗。
数据库端
create or replace FUNCTION getBlobWrp (username IN VARCHAR2) RETURN BLOB
AS LANGUAGE JAVA NAME
'TestBlob.getBlob(java.lang.String) return oracle.sql.BLOB';
测试:
DECLARE
l_blob BLOB;
BEGIN
l_blob := getBlobWrp('test');
dbms_output.put_line(UTL_RAW.CAST_TO_VARCHAR2(l_blob));
END;
输出:
test
(previous answer)
I think you should have an IN OUT BLOB
parameter in your test_create_excel
function (change it to a procedure), and operate on that parameter inside your Java stored method. I saw that approach once.
Before calling the test_create_excel
, you should create a BLOB
object:
DECLARE
l_blob BLOB;
BEGIN
DBMS_LOB.createtemporary(l_blob, TRUE);
test_create_excel('username', l_blob);
END;
编辑
我认为您尝试做的事情是不可能的。但是,您可以将上面的代码包装在另一个函数中。这有点困惑,但是您将拥有一个返回 blob 的函数:
CREATE OR REPLACE FUNCTION get_excel_blob(p_username VARCHAR2) RETURN BLOB
AS
l_blob BLOB;
BEGIN
DBMS_LOB.createtemporary(l_blob, TRUE);
test_create_excel(p_username, l_blob);
RETURN l_blob;
END;
关于java - 在 java 存储过程中创建 java.sql.blob 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20072410/