在执行接受并返回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;
...
答案 0 :(得分:0)
您需要从Java过程返回oracle.sql.BLOB
或oracle.jdbc2.Blob
的实例,以便创建调用Java过程并返回BLOB的触发器。 ORACLE实际上有一个表,他们将数据类型与它们可以接受的Java实例进行比较:
更新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)
这是我在临近截止日期后实施的临时解决方案,我仍在寻找一种解决方案,其中不必使用不推荐使用的类,并且希望避免引用oracle.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);
}