java - 在 java 存储过程中创建 java.sql.blob 实例

标签 java sql oracle stored-procedures

这是我第一次在 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/

相关文章:

sql - SOLR DataImportHandler,如何将嵌套实体视为 JSON 数组

sql - 在mysql中设计动态键值对的最佳方法是什么?

sql - 如何格式化时间戳

mysql - 我无法在 oracle 数据库上创建具有可变类型 long 的类型对象

java - 是具有私有(private)访问修饰符的变量..对于使用该类定义创建的新​​对象不可见?

java - 如何读取动态Excel文件?

java - 如何获取 Spring REST 文件下载以返回 404?

php - MySQL:分组并计算多个字段

java - 将 maven-gae 和 google 插件用于 eclipse (GPE) 时出错

linux - 连接 Oracle DB sqlplus/as sysdba 的问题(未设置 TWO_TASK)