You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ORA-06550/PLS-00382错误排查:P41_ATTACHMENT文件上传问题

ORA-06550/PLS-00382 类型不匹配错误排查与解决

问题背景

执行PL/SQL过程时触发错误:

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

错误指向P41_ATTACHMENT变量的类型匹配问题,相关代码、表结构及项配置如下:

涉事PL/SQL代码

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;

QDL_SCRAP_REQUESTS表结构

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

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 

错误原因分析

错误出现在第5行v_blob BLOB := :P41_ATTACHMENT;,核心原因是:

  • Oracle APEX中,当文件上传项配置为"BLOB column specified in Item Source attribute"时,绑定变量:P41_ATTACHMENT返回的并非直接的BLOB对象,而是APEX_APPLICATION_FILES表中的文件ID(VARCHAR2类型)
  • 直接将VARCHAR2类型的文件ID赋值给BLOB类型变量,触发类型不匹配

解决步骤

方案1:直接使用绑定变量插入(推荐)

无需提前声明BLOB变量,直接在INSERT语句中引用:P41_ATTACHMENT,APEX会自动处理类型转换:

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_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
    -- 保留原有校验逻辑...

    -- 插入部分修改:直接使用:P41_ATTACHMENT
    IF :P41_ATTACHMENT IS NOT NULL THEN
        INSERT INTO QDL_SCRAP_REQUESTS (
            REQ_ID,
            REQ_DATE,
            REQUESTOR,
            DISPOSAL_TYPE,
            PART_NUMBER,
            HU,
            STATUS,
            QTY,
            PPM,
            TE_MIN,
            COMMENTS,
            OVERDUE,
            QSB_APPROVED,
            APPROVAL_DATE,
            CLAIM_NUM,
            ATTACHMENT,
            MIMETYPE,
            FILENAME,
            ATTCH_UPDATE,
            QSP_APPROVAL_DATE
        ) VALUES (
            QDL_SCRAP_REQUESTS_SEQ.NEXTVAL,
            TO_TIMESTAMP(:P41_RELOJ_EN_TIEMPO_REAL, 'DD/MM/YYYY HH24:MI:SS'),
            :P41_REQUESTOR,
            :P41_DISPOSAL_TYPE,
            :P41_PART_NUMBER,
            :P41_HU,
            'yellow',
            :P41_QTY,
            :P41_PPM,
            :P41_TE_MIN,
            :P41_COMMENTS,
            'N',
            NULL,
            NULL,
            :P41_CLAIM_NUM,
            :P41_ATTACHMENT, -- 直接引用绑定变量
            v_mimetype,
            v_filename,
            v_last_updated,
            NULL
        );
    ELSE
        -- 保留原有无文件插入逻辑...
    END IF;

    COMMIT;
END;

方案2:通过文件ID查询BLOB(适合需提前处理文件内容的场景)

如果需要在插入前处理BLOB内容,可通过文件ID从APEX_APPLICATION_FILES中获取实际BLOB:

DECLARE
    v_part_number_list VARCHAR2(4000) := :P41_PART_NUMBER;
    v_invalid_part_numbers VARCHAR2(4000);
    v_part_number VARCHAR2(255);
    v_blob BLOB; -- 仅声明不初始化
    v_mimetype VARCHAR2(100) := :P41_MIMETYPE;
    v_filename VARCHAR2(100) := :P41_FILENAME;
    v_last_updated TIMESTAMP := SYSTIMESTAMP;
BEGIN
    -- 获取文件BLOB
    IF :P41_ATTACHMENT IS NOT NULL THEN
        SELECT blob_content INTO v_blob
        FROM apex_application_files
        WHERE name = :P41_ATTACHMENT;
    END IF;

    -- 保留原有校验和插入逻辑,插入时使用v_blob...
END;

额外优化建议

  1. 替换:P41_QTY和:P41_HU的正则校验为TO_NUMBER异常捕获,更符合Oracle类型处理规范:
BEGIN
    :P41_QTY := TO_NUMBER(:P41_QTY);
EXCEPTION
    WHEN VALUE_ERROR THEN
        RAISE_APPLICATION_ERROR(-20004, 'Invalid Quantity (QTY): ' || :P41_QTY);
END;
  1. 表中QTY、HU为NUMBER类型,插入时直接传入:P41_QTY即可,无需额外格式校验

内容的提问来源于stack exchange,提问作者fesm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:58:10