【问题标题】:PLS-00049 bad bind variable 'NEW.NUM_CUENTA'PLS-00049 错误绑定变量 'NEW.NUM_CUENTA'
【发布时间】:2019-11-22 17:14:20
【问题描述】:

我在 Oracle 中为名为 empleado 的视图执行此触发器,但出现此错误

18/40 PLS-00049 错误绑定变量“NEW.NUM_CUENTA”

谁能帮我看看我做错了什么

触发器是:

create or replace trigger t_dml_empleado
instead of insert or delete on empleado
declare

begin 
    case 
        when inserting then 
            if (SUBSTR(rfc, 1,1) BETWEEN 'A' and 'M') then 
                insert into empleado_2 (empleado_id, nombre, ap_paterno, ap_materno, rfc, email, jefe_id)
                values(:new.empleado_id, :new.nombre, :new.ap_paterno, :new.ap_materno, 
                        :new.rfc, :new.email, :new.jefe_id);
            elsif (SUBSTR(rfc, 1,1) BETWEEN 'N' and 'Z')    then 
                insert into empleado_3 (empleado_id, nombre, ap_paterno, ap_materno, rfc, email, jefe_id)
                values (:new.empleado_id, :new.nombre, :new.ap_paterno, :new.ap_materno,
                        :new.rfc, :new.email, :new.jefe_id);
            else
                raise_application_error(20001,'Valor incorrecto para RFC: '|| :new.rfc);
            end if;
            insert into empleado_1(empleado_id, foto, num_cuenta)
            values (:new.empleado_id, :new.foto,:new.num_cuenta);

        when deleting then 
            if (SUBSTR(rfc, 1,1) BETWEEN 'A' and 'M')  then 
                delete from empleado_2 where empleado_id =:old.empleado_id;
            elsif (SUBSTR(rfc, 1,1) BETWEEN 'N' and 'Z')    then
                delete from empleado_3 where empleado_id = :old.empleado_id;            
            else
                raise_application_error(20001,'Valor incorrecto para RFC: '|| :new.rfc);
            end if;
            delete from empleado_1 where empleado_id = :old.empleado_id;
    end case;
end;

在第二行解释 empleado 是一个视图,它在一个 PDB 中:

create or replace view empleado as
    select q1.empleado_id, q1.nombre, q1.ap_paterno, q1.ap_materno, q1.rfc,q1.email, q1.jefe_id, foto
    from (
            select empleado_id, nombre, ap_paterno, ap_materno, rfc,email, jefe_id 
            from empleado_2
            union
            select empleado_id, nombre, ap_paterno, ap_materno, rfc,email, jefe_id 
            from empleado_3
         ) q1,(select empleado_id, foto, num_cuenta 
                   from empleado_1) q2
            where q1.empleado_id=q2.empleado_id;

这是来自三个表 empleado_3empleado_1 在一个 PDB 中,empleado_2 在另一个 PDB 中。该视图正在连接远程表。

我创建了同义词,所以问题不存在。这些表格是:


CREATE TABLE F_AMG_EMPLEADO_1
(
    EMPLEADO_ID          NUMERIC(10,0) NOT NULL ,
    FOTO                 BLOB NOT NULL ,
    NUM_CUENTA           VARCHAR2(18) NOT NULL 
);
CREATE TABLE F_AMG_EMPLEADO_3
(
    EMPLEADO_ID          NUMERIC(10,0) NOT NULL ,
    NOMBRE               VARCHAR2(40) NOT NULL ,
    AP_PATERNO           VARCHAR2(40) NOT NULL ,
    AP_MATERNO           VARCHAR2(40) NOT NULL ,
    RFC                  VARCHAR2(13) NOT NULL ,
    EMAIL                VARCHAR2(40) NOT NULL ,
    JEFE_ID              NUMERIC(10,0) NULL 
);

【问题讨论】:

    标签: sql plsql oracle18c


    【解决方案1】:

    在视图 empleado 中,您没有名为 num_cuenta 的列。 您必须在视图中选择它,就像我在 DEMO 中所做的那样。

    接下来的错误是在 WHEN INSERTING 和 WHEN DELETING 的触发器中使用大小写。我用if then elsif改变了它

    接下来不好的是在 SUBSTR 函数中使用 rfc。你必须引用一个 :new 或 :old 值,就像我在我的演示中所使用的那样。这是起作用的触发器:

    create or replace trigger t_dml_empleado
    instead of insert or delete on empleado
    declare
    
    begin 
        if inserting then 
                if (SUBSTR(:new.rfc, 1,1)) BETWEEN 'A' and 'M' then
                   insert into empleado_2 (empleado_id, nombre, ap_paterno, ap_materno, rfc, email, jefe_id)
                    values(:new.empleado_id, :new.nombre, :new.ap_paterno, :new.ap_materno, 
                            :new.rfc, :new.email, :new.jefe_id);
                elsif (SUBSTR(:new.rfc, 1,1) BETWEEN 'N' and 'Z') then 
                    insert into empleado_3 (empleado_id, nombre, ap_paterno, ap_materno, rfc, email, jefe_id)
                    values (:new.empleado_id, :new.nombre, :new.ap_paterno, :new.ap_materno,
                            :new.rfc, :new.email, :new.jefe_id);
                 else
                    raise_application_error(20001,'Valor incorrecto para RFC: '|| :new.rfc);
                end if;
        elsif deleting then 
                if (SUBSTR(:old.rfc, 1,1)) BETWEEN 'A' and 'M'  then 
                    delete from empleado_2 where empleado_id =:old.empleado_id;
                elsif (SUBSTR(:new.rfc, 1,1) BETWEEN 'N' and 'Z')    then
                    delete from empleado_3 where empleado_id = :old.empleado_id;            
                else
                    raise_application_error(20001,'Valor incorrecto para RFC: '|| :new.rfc);
                end if;
                delete from empleado_1 where empleado_id = :old.empleado_id;
        end if;
    end;
    /
    

    这里是DEMO。 我希望这能帮助您解决问题。 干杯!

    【讨论】:

    • 非常感谢,我希望我也能给你正确的答案,是的,如果语句给我带来了一些麻烦,你的解决方案是一种解脱
    • 嗨@Arturo,不客气。太糟糕了,这不是正确的答案,因为缺少列的问题很容易找到,其他错误也不多....奇怪...
    【解决方案2】:

    这是您视图的投影:

    select q1.empleado_id, q1.nombre, q1.ap_paterno, q1.ap_materno, q1.rfc,q1.email, q1.jefe_id, foto
    

    这些是唯一的列,您可以在基于该视图的触发器t_dml_empleado 中引用。如您所见,视图的投影中没有提到num_cuenta。因此,您不能在触发器中引用 :new.num_cuenta

    至于解决方案,要么更改触发器,要么将num_cuenta 添加到视图定义中选择的列中。

    【讨论】:

    • 我也看到了这个,但是我添加了专栏,仍然有错误......也许我错了......检查这个:dbfiddle.uk/…
    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 2017-08-16
    • 2019-06-05
    • 2015-08-09
    • 1970-01-01
    • 2020-10-22
    • 2022-06-13
    • 2016-01-03
    相关资源
    最近更新 更多