这是我第一次发布问题,我需要编写一个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:数据类型不一致:预期的返回值是用户定义的Java类的实例,该实例可以转换为Oracle类型,但返回的对象无法转换
有没有人遇到过这个问题,如果可以的话,您可以分享如何解决这个问题。
先感谢您。
编辑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。
我使用’ sys.dbms_java.loadjava ‘加载了参考jar和为我的代码创建的jar 。
我希望您能理解我的问题,因为我对PL / SQL编程还很陌生
我错了。它 可以 完成。花了我一段时间才能使其正常工作,但是最后,这是一个有效的示例:
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结果。我使用类的静态createTemporary方法创建它,并BLOB指定应在会话期间(oracle.sql.BLOB.DURATION_SESSION参数)创建它。
oracle.sql.BLOB
createTemporary
BLOB
oracle.sql.BLOB.DURATION_SESSION
然后,我获得OutputStream并写入数据。需要冲洗。
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;
输出:
测试
(先前的答案)
我认为您应该IN OUT BLOB在test_create_excel函数中有一个参数(将其更改为过程),并在Java存储方法中对该参数进行操作。我曾经见过这种方法。
IN OUT BLOB
test_create_excel
在调用之前test_create_excel,您应该创建一个BLOB对象:
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;