【问题标题】:Create java.sql.blob instance in java stored procedure在 java 存储过程中创建 java.sql.blob 实例
【发布时间】:2013-12-03 01:21:39
【问题描述】:

这是我第一次在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:不一致的数据类型:预期返回值是 可转换为 Oracle 类型的用户定义 Java 类的实例 得到一个无法转换的对象

有没有人遇到过这个问题,如果有,您可以分享一下您是如何解决的。

在此先感谢您。

编辑 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 编程很陌生

【问题讨论】:

  • 你不能在 oracle 中使用数据类型,只有支持的数据类型才有效。
  • 这是我的错误,将我的代码粘贴到此处时,该方法不返回 ExcelFileStore。我编辑了我的问题,对此感到抱歉。

标签: java sql oracle stored-procedures


【解决方案1】:

我错了。它可以完成。我花了一段时间才让它工作,但最后,这是一个工作示例:

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 方法创建它,指定它应该在会话期间创建(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_create_excel 函数中有一个IN OUT BLOB 参数(将其更改为一个过程),并在您的Java 存储方法中对该参数进行操作。这种方法我见过一次。

在调用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;

【讨论】:

  • 谢谢,我确实尝试过类似的方法,在 pl/sql 中创建一个临时 blob 并将其传递给 java 方法,但如果我可以在 java 中创建 blob 会更干净本身。再次感谢您
  • 谢谢 Przemyslaw,我想我会使用这种方法。
  • @harindya 很抱歉我的第一个误导性回答。 可以完成,BLOB 映射到oracle.sql.BLOB 类。请检查我编辑的答案。
  • 再次非常感谢您的帮助,我尝试了您在 java 中创建 blob 的方法,一切正常,但是当我在 pl/sql 中运行该过程时,我得到以下 java NTO.Excel.ExcelFunctions 的 NTO.Excel.ExcelFunctions.getBlob(ExcelFunctions.java:66) 的 oracle.sql.BLOB.createTemporary(BLOB.java:671) 的线程“根线程”java.lang.IncompatibleClassChangeError 中的异常异常。 PushToExcel(ExcelFunctions.java:169) 我需要将引用 jar 加载到 oracle。我正在使用jdk1.5。你知道我为什么会收到这个异常吗?
  • @harindya 错误很奇怪。我的建议是:试试我的例子,看看它是否适合你。另外,请检查此线程以获取错误的可能解决方案:IncompatibleClassChangeError In Java 我建议您从数据库和包装函数中删除所有与 Java 相关的代码(全部删除)并尝试再次导入它。我认为您不应该加载参考 jar,除非您收到缺少某些类的错误。在我的示例中,我没有加载任何额外的 jar。
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 2018-07-27
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
相关资源
最近更新 更多