Oracle Java: ошибка приведения типа данных java.sql.Blob к типу данных Oracle BLOB - PullRequest
0 голосов
/ 02 февраля 2019

Я получаю следующую ошибку при выполнении процедуры Oracle Java, которая принимает и возвращает BLOB-данные,

Отчет об ошибке - 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;
...

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Это временное решение, которое я реализовал, так как я приближался к крайнему сроку, я все еще в поиске решения, в котором мне не нужно использовать устаревшие классы, и я хотел бы избежать ссылки на 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;

}

Я настроил вознаграждение, чтобы получить решение для решения этой проблемы без использования устаревшего класса, и яне смог найти один, хотя я получил внимание на этот вопрос.Это открытая проблема для меня, пока я не найду правильное решение.Спасибо всем, кто приложил усилия.

С уважением!

0 голосов
/ 06 февраля 2019

Вам необходимо вернуть экземпляр oracle.sql.BLOB или oracle.jdbc2.Blob из вашей Java-процедуры, чтобы создать триггер, который вызывает 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

Можете ли вы попробовать запустить приведенный выше код и посмотреть, если вы получите ту же ошибку?

...