plsqloracle-apex

ORA-06550: line 5, column 20: PLS-00382: expression is of wrong type


I have this process Im reciving an error that seems to be related with the item P41_ATTACHMENT to upload a file in this table QDL_SCRAP_REQUESTS.

DECLARE
    v_part_number_list VARCHAR2(4000) := :P41_PART_NUMBER;
    v_invalid_part_numbers VARCHAR2(4000); -- Almacena valores no válidos
    v_part_number VARCHAR2(255);          -- Almacena cada valor de la lista
    v_blob BLOB := :P41_ATTACHMENT;      -- Archivo cargado
    v_mimetype VARCHAR2(100) := :P41_MIMETYPE; -- Tipo MIME del archivo
    v_filename VARCHAR2(100) := :P41_FILENAME; -- Nombre del archivo
    v_last_updated TIMESTAMP := SYSTIMESTAMP;  -- Fecha/Hora de la carga
BEGIN
    -- Validar que todos los valores en la lista de PART_NUMBER sean alfanuméricos
    FOR part_number IN (
        SELECT TRIM(REGEXP_SUBSTR(v_part_number_list, '[^,]+', 1, LEVEL)) AS part_number
        FROM DUAL
        CONNECT BY REGEXP_SUBSTR(v_part_number_list, '[^,]+', 1, LEVEL) IS NOT NULL
    ) LOOP
        v_part_number := part_number.part_number;

        -- Ignorar valores vacíos
        IF v_part_number IS NULL OR v_part_number = '' THEN
            CONTINUE;
        END IF;

        -- Si el valor no es alfanumérico, agregarlo a la lista de valores inválidos
        IF NOT REGEXP_LIKE(v_part_number, '^[A-Za-z0-9]+$') THEN
            v_invalid_part_numbers := NVL(v_invalid_part_numbers || ',', '') || v_part_number;
        END IF;
    END LOOP;

    -- Si hay valores no válidos en PART_NUMBER, generar un error
    IF v_invalid_part_numbers IS NOT NULL THEN
        RAISE_APPLICATION_ERROR(-20003, 'Invalid Part Number(s): ' || v_invalid_part_numbers);
    END IF;

    -- Validar que otros campos numéricos sean correctos
    IF NOT REGEXP_LIKE(:P41_QTY, '^\d+$') THEN
        RAISE_APPLICATION_ERROR(-20004, 'Invalid Quantity (QTY): ' || :P41_QTY);
    END IF;

    IF NOT REGEXP_LIKE(:P41_HU, '^\d+$') THEN
        RAISE_APPLICATION_ERROR(-20005, 'Invalid HU value: ' || :P41_HU);
    END IF;

    -- Insertar los datos en la tabla, incluyendo el archivo y sus metadatos
    IF v_blob IS NOT NULL THEN
        INSERT INTO QDL_SCRAP_REQUESTS (
            REQ_ID,
            REQ_DATE,
            REQUESTOR,
            DISPOSAL_TYPE,
            PART_NUMBER,
            HU,
            STATUS, -- Siempre se inserta como "yellow"
            QTY,
            PPM,
            TE_MIN,
            COMMENTS,
            OVERDUE,
            QSB_APPROVED,
            APPROVAL_DATE,
            CLAIM_NUM,
            ATTACHMENT, -- Archivo cargado
            MIMETYPE,   -- Tipo MIME del archivo
            FILENAME,   -- Nombre del archivo
            ATTCH_UPDATE, -- Fecha de carga
            QSP_APPROVAL_DATE
        ) VALUES (
            QDL_SCRAP_REQUESTS_SEQ.NEXTVAL, -- Genera REQ_ID automáticamente
            TO_TIMESTAMP(:P41_RELOJ_EN_TIEMPO_REAL, 'DD/MM/YYYY HH24:MI:SS'), -- Fecha del reloj
            :P41_REQUESTOR,                -- Requestor
            :P41_DISPOSAL_TYPE,            -- Disposal Type
            :P41_PART_NUMBER,              -- Part Number
            :P41_HU,                       -- HU
            'yellow',                      -- STATUS: Siempre se inserta como "yellow"
            :P41_QTY,                      -- Qty
            :P41_PPM,                      -- PPM
            :P41_TE_MIN,                   -- TE_MIN
            :P41_COMMENTS,                 -- Comments
            'N',                           -- Overdue
            NULL,                          -- QSB Approved
            NULL,                          -- Approval Date
            :P41_CLAIM_NUM,                -- Claim Num
            v_blob,                        -- Archivo cargado
            v_mimetype,                    -- Tipo MIME
            v_filename,                    -- Nombre del archivo
            v_last_updated,                -- Fecha de carga
            NULL                           -- QSP Approval Date
        );
    ELSE
        -- Si no se cargó un archivo, insertar los datos sin archivo
        INSERT INTO QDL_SCRAP_REQUESTS (
            REQ_ID,
            REQ_DATE,
            REQUESTOR,
            DISPOSAL_TYPE,
            PART_NUMBER,
            HU,
            STATUS, -- Siempre se inserta como "yellow"
            QTY,
            PPM,
            TE_MIN,
            COMMENTS,
            OVERDUE,
            QSB_APPROVED,
            APPROVAL_DATE,
            CLAIM_NUM,
            ATTACHMENT, -- Archivo vacío
            MIMETYPE,   -- Tipo MIME vacío
            FILENAME,   -- Nombre vacío
            ATTCH_UPDATE, -- Fecha de carga vacía
            QSP_APPROVAL_DATE
        ) VALUES (
            QDL_SCRAP_REQUESTS_SEQ.NEXTVAL, -- Genera REQ_ID automáticamente
            TO_TIMESTAMP(:P41_RELOJ_EN_TIEMPO_REAL, 'DD/MM/YYYY HH24:MI:SS'), -- Fecha del reloj
            :P41_REQUESTOR,                -- Requestor
            :P41_DISPOSAL_TYPE,            -- Disposal Type
            :P41_PART_NUMBER,              -- Part Number
            :P41_HU,                       -- HU
            'yellow',                      -- STATUS: Siempre se inserta como "yellow"
            :P41_QTY,                      -- Qty
            :P41_PPM,                      -- PPM
            :P41_TE_MIN,                   -- TE_MIN
            :P41_COMMENTS,                 -- Comments
            'N',                           -- Overdue
            NULL,                          -- QSB Approved
            NULL,                          -- Approval Date
            :P41_CLAIM_NUM,                -- Claim Num
            EMPTY_BLOB(),                  -- Archivo vacío
            NULL,                          -- Tipo MIME vacío
            NULL,                          -- Nombre vacío
            NULL,                          -- Fecha de carga vacía
            NULL                           -- QSP Approval Date
        );
    END IF;

    -- Confirmar los cambios
    COMMIT;
END;

This is the structure of the table:

Column Name Data Type   Nullable    Default Primary Key Comment Identity
REQ_ID  NUMBER  Y               
REQ_DATE    TIMESTAMP(9)    Y               
REQUESTOR   VARCHAR2(50 BYTE)   Y               
DISPOSAL_TYPE   VARCHAR2(50 BYTE)   Y               
PART_NUMBER VARCHAR2(4000 BYTE) Y               
HU  VARCHAR2(4000 BYTE) Y               
STATUS  VARCHAR2(500 BYTE)  Y               
QTY NUMBER  Y               
PPM NUMBER  Y               
TE_MIN  NUMBER  Y               
COMMENTS    VARCHAR2(4000 BYTE) Y               
OVERDUE VARCHAR2(1 BYTE)    Y               
QSB_APPROVED    VARCHAR2(1 BYTE)    Y               
APPROVAL_DATE   TIMESTAMP(9)    Y               
CLAIM_NUM   VARCHAR2(4000 BYTE) Y               
MIMETYPE    VARCHAR2(50 BYTE)   Y               
FILENAME    VARCHAR2(200 BYTE)  Y               
ATTCH_UPDATE    TIMESTAMP(9)    Y               
QSP_APPROVAL    VARCHAR2(1 BYTE)    Y               
QSP_APPROVAL_DATE   TIMESTAMP(9)    Y               
ATTACHMENT  BLOB    Y

The item P41_ATTACHMENT:

Storage
Type BLOB column specified in Item Source attribute
MIME Type Column MIMETYPE
Filename Column FILENAME
Character Set Column BLOB 
Last Updated Column ATTCH_UPDATE 

Solution

  • That is not how a file upload works. The file content cannot be used as a bind variable which is why the error PLS-00382: expression is of wrong type is thrown. This line:

        v_blob BLOB := :P41_ATTACHMENT; 
    

    is not valid. There is a sample application in the Gallery that shows how to upload a file in the table and the official docs also have a section on this. AFAIK the file upload always has to be done by a native APEX form process. At first glance it seems pretty straightforward to change your code into a native APEX form region and not use custom pl/sql :

    ...
    BEGIN
    --
    -- following code should be moved to a validation instead of in this page process
    --
        -- Validar que todos los valores en la lista de PART_NUMBER sean alfanuméricos
        FOR part_number IN (
            SELECT TRIM(REGEXP_SUBSTR(v_part_number_list, '[^,]+', 1, LEVEL)) AS part_number
            FROM DUAL
            CONNECT BY REGEXP_SUBSTR(v_part_number_list, '[^,]+', 1, LEVEL) IS NOT NULL
        ) LOOP
    ...
    
        IF NOT REGEXP_LIKE(:P41_HU, '^\d+$') THEN
            RAISE_APPLICATION_ERROR(-20005, 'Invalid HU value: ' || :P41_HU);
        END IF;
    
    --
    -- insert/update can be handled by the native form page process.
    --
    
        -- Insertar los datos en la tabla, incluyendo el archivo y sus metadatos
        IF v_blob IS NOT NULL THEN
            INSERT INTO QDL_SCRAP_REQUESTS (
                REQ_ID,
                REQ_DATE,
    ...
                NULL,                          -- Fecha de carga vacía
                NULL                           -- QSP Approval Date
            );
        END IF;
    
        -- Confirmar los cambios
    --
    -- let APEX handle commits for you, this is not needed.
    --
        COMMIT;
    END;