[英]Oracle Java: Error casting java.sql.Blob datatype to Oracle BLOB datatype
在執行接受並返回 BLOB 數據的 Oracle Java 過程時出現以下錯誤,
錯誤報告 - ORA-00932:不一致的數據類型:預期的返回值是可轉換為 Oracle 類型的用戶定義的 Java 類的實例得到了無法轉換的對象 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;
}
甲骨文代碼
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;
...
您需要從Java過程返回oracle.sql.BLOB
或oracle.jdbc2.Blob
的實例,以便創建一個調用Java過程並返回BLOB的觸發器。 ORACLE實際上有一個表,他們將數據類型與他們可以接受的Java實例進行比較:
合法數據類型映射。 Oracle數據庫自動在SQL類型和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
你能嘗試運行上面的代碼,看看你是否得到了同樣的錯誤?
這是我實施的一個臨時解決方案,因為我接近截止日期,我仍然在尋找一個解決方案,其中我不必使用棄用的類,並且希望避免引用oracle.sql.BLOB並使用java .sql.Blob。
解決方法涉及創建oracle.sql.BLOB對象而不是SerialBlob,然后從輸出流填充bytearray,如下所示,
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;
}
我設置了一個賞金來獲得一個解決方案來解決這個問題沒有使用已棄用的類我無法找到一個,雖然我收到了這個問題的注意。 在找到正確的解決方案之前,這對我來說是一個懸而未決的問題 感謝所有努力的人。
問候!
我找到了這個沒有棄用代碼的解決方案:
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.