Oracle Java:将java.sql.Blob数据类型转换为Oracle BLOB数据类型时出错

时间:2019-02-02 00:26:26

标签: java oracle java-7 oracle12c

在执行接受并返回BLOB数据的Oracle Java过程时,出现以下错误,

  

错误报告-ORA-00932:数据类型不一致:预期会返回   是用户定义的Java类的实例的值,可以转换为   Oracle类型获得了无法转换的对象ORA-06512:在   “”,第86行ORA-06512:在第7行   00932。00000-“数据类型不一致:预期的%s得到了%s”   *原因:
  *动作:

Java代码

public static java.sql.Blob Convert_Image(java.sql.Blob srcBlob) {

java.sql.Blob desBlob = null;

try {
    Document document = new Document();

    ByteArrayOutputStream pdfDocumentOutputStream = new ByteArrayOutputStream();
    PdfWriter pdfDocumentWriter = PdfWriter.getInstance(document, pdfDocumentOutputStream);                        
    document.open();

    if (document.newPage()) {

        int indentation = 0;
        Image img = Image.getInstance(srcBlob.getBytes(1, (int) srcBlob.length()));
        float scaler = document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin() - indentation;
        img.scalePercent((scaler / img.getWidth()) * 100);

        document.newPage();
        document.add(Image.getInstance(img));
        document.close();

        desBlob = new SerialBlob(pdfDocumentOutputStream.toByteArray());

        pdfDocumentWriter.close();
        pdfDocumentOutputStream.close();

    }   
}
catch (Exception e) {
    Show_Message(e);
}

return desBlob;

}

Oracle代码

FUNCTION CONVERT_IMAGE(
    P_BLOB IN DOCUMENTS.BLOB_CONTENT%TYPE)
  RETURN BLOB
AS
  LANGUAGE JAVA NAME 'egift.Util.Convert_Image (java.sql.Blob) return java.sql.Blob';  

触发实施

...
DECLARE

    v_blob_content DOCUMENTS.BLOB_CONTENT%TYPE;

BEGIN

    IF :NEW.BLOB_CONTENT IS NOT NULL AND 
      (
        NVL(:NEW.MIME_TYPE,'#') = 'image/png' OR 
        NVL(:NEW.MIME_TYPE,'#') = 'image/jpeg' OR 
        NVL(:NEW.MIME_TYPE,'#') = 'image/gif' OR
        NVL(:NEW.MIME_TYPE,'#') = 'image/tiff' OR
        NVL(:NEW.MIME_TYPE,'#') = 'image/bmp'
      ) THEN
      v_blob_content := EGIFT_UTIL.CONVERT_IMAGE(:NEW.BLOB_CONTENT);
      IF v_blob_content is not null then
        :NEW.BLOB_CONTENT := v_blob_content;  
        :NEW.MIME_TYPE := 'application/pdf';
        :NEW.NAME := substr(:NEW.NAME,0,instr(:NEW.NAME,'.',-1)) || 'pdf';
      END IF;
    END IF;
...

3 个答案:

答案 0 :(得分:0)

您需要从Java过程返回oracle.sql.BLOBoracle.jdbc2.Blob的实例,以便创建调用Java过程并返回BLOB的触发器。 ORACLE实际上有一个表,他们将数据类型与它们可以接受的Java实例进行比较:

the legal data type mappings. Oracle Database converts between the SQL types and Java classes automatically

更新1: 我实际上测试了传递java.sql.Blob并在函数中返回相同的类型,并且按预期工作:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "Util" as
public class Util {
  public static java.sql.Blob Convert_Image(java.sql.Blob srcBlob) {

    return srcBlob;

    }
}
/

CREATE OR REPLACE FUNCTION CONVERT_IMAGE(
    P_BLOB BLOB)
  RETURN BLOB
AS
  LANGUAGE JAVA NAME 'Util.Convert_Image (java.sql.Blob) return java.sql.Blob';


select utl_raw.cast_to_varchar2(convert_image(utl_raw.cast_to_raw('test'))) from dual;
-- test

您可以尝试运行上面的代码,看看是否遇到相同的错误吗?

答案 1 :(得分:0)

这是我在临近截止日期后实施的临时解决方案,我仍在寻找一种解决方案,其中不必使用不推荐使用的类,并且希望避免引用o​​racle.sql.BLOB并使用java.sql.Blob。

解决方法涉及创建一个oracle.sql.BLOB对象而不是SerialBlob,然后按如下所示从输出流中填充字节数组,

conn = new OracleDriver().defaultConnection();
desBlob = BLOB.createTemporary(conn, false, BLOB.DURATION_SESSION);
desBlob.setBytes(1, pdfDocumentOutputStream.toByteArray());

使用以下禁止显示的过时警告

@SuppressWarnings("deprecation")

最终Java代码

@SuppressWarnings("deprecation")
public static java.sql.Blob Convert_Image(java.sql.Blob srcBlob) {

    java.sql.Blob desBlob = null;

    try {
        Document document = new Document();

        ByteArrayOutputStream pdfDocumentOutputStream = new ByteArrayOutputStream();
        PdfWriter pdfDocumentWriter = PdfWriter.getInstance(document, pdfDocumentOutputStream);
        document.open();

        if (document.newPage()) {

            int indentation = 0;
            Image img = Image.getInstance(srcBlob.getBytes(1, (int) srcBlob.length()));
            float scaler =
                document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin() - indentation;
            img.scalePercent((scaler / img.getWidth()) * 100);

            document.newPage();
            document.add(Image.getInstance(img));
            document.close();

            //desBlob = new SerialBlob(pdfDocumentOutputStream.toByteArray());
            conn = new OracleDriver().defaultConnection();
            desBlob = BLOB.createTemporary(conn, false, BLOB.DURATION_SESSION);
            desBlob.setBytes(1, pdfDocumentOutputStream.toByteArray());

            pdfDocumentWriter.close();
            pdfDocumentOutputStream.close();

        }
    } catch (Exception e) {
        Show_Message(e);
    }
    return desBlob;

}

我已经设置了赏金来获得解决方案,该解决方案不建议使用不推荐使用的类来解决此问题,尽管我对此问题有所注意,但我却找不到。在我找到正确的解决方案之前,这对我来说是一个悬而未决的问题。感谢所有的努力。

致谢!

答案 2 :(得分:0)

我发现此解决方案没有弃用的代码:

    public static Blob bytes2Blob(byte[] b) throws Exception {
        if (System.getProperty("oracle.server.version") != null) {
            Connection con = DriverManager.getConnection("jdbc:default:connection");
            CallableStatement cStmt = con.prepareCall ("{ call DBMS_LOB.createtemporary(?,true,DBMS_LOB.SESSION) }");
            cStmt.registerOutParameter(1, OracleTypes.BLOB);
            cStmt.execute();
            Blob blob = ((OracleCallableStatement)cStmt).getBLOB(1);
            cStmt.close();
            OutputStream out = blob.setBinaryStream(1L);
            out.write(b);
            out.flush();
            return blob;
        } else {
            return new javax.sql.rowset.serial.SerialBlob(b);
        }