【问题标题】:PLS-00049: bad bind variable TriggersPLS-00049:错误的绑定变量触发器
【发布时间】:2017-08-11 05:47:38
【问题描述】:

我正在尝试使此触发器起作用。它的作用是,这将在从表及其附属表中删除数据之前执行,然后将删除的数据插入 2 个表(我将其命名为 tb1_arch 和 tb2_arch)。我一直在谷歌搜索可能的修复,但我真的不知道如何使这项工作

CREATE OR REPLACE TRIGGER trig
BEFORE DELETE ON tb1 FOR EACH ROW
FETCH
INSERT INTO tb1_arch VALUES (:old.OrderNum, :old.tb1Date,:old.CustomerName);
DBMS_OUTPUT.PUT_LINE('Data archived.');
END;

触发器是在上面创建的。但是当我添加这一行时

INSERT INTO tb2_arch VALUES (:old.OrderNum, :old.ItemNum, :old.Pieces);

INSERT INTO tb1_arch VALUES 之后,它给了我一个错误

“第 5 行错误:PLS-00049:绑定变量 'OLD.PIECES' 错误”

任何帮助将不胜感激!

编辑:正如 Vijayakumar 先生所建议的,我做了以下事情:

CREATE OR REPLACE TRIGGER trig
    BEFORE DELETE ON tb1 
    REFERENCING OLD AS old FOR EACH ROW
    INSERT INTO tb1_arch VALUES (:old.OrderNum, :old.tb1Date,:old.CustomerName);
    INSERT INTO tb2_arch VALUES (:old.OrderNum, :old.ItemNum, :old.Pieces);
    DBMS_OUTPUT.PUT_LINE('Data archived.');
    END

但是,我仍然遇到同样的错误。

编辑:删除了 FETCH,我仍然遇到同样的问题

CREATE OR REPLACE TRIGGER trig
BEFORE DELETE ON tb1 FOR EACH ROW

INSERT INTO tb1_arch VALUES (:old.OrderNum, :old.tb1Date,:old.CustomerName);
INSERT INTO tb2_arch VALUES (:old.OrderNum, :old.ItemNum, :old.Pieces);
DBMS_OUTPUT.PUT_LINE('Data archived.');
END;

表格如下: 待定1:

create table tb1 (
    OrderNum integer NOT NULL primary key,
    tb1Date date NOT NULL,
    CustomerName varchar2(50) NOT NULL,

--constraints
    CONSTRAINT tb1_uc unique (CustomerName)
);  

tb2

create table tb2 (
    OrderNum integer NOT NULL,
    ItemNum integer NOT NULL,
    Pieces integer NOT NULL,

--constraints
    CONSTRAINT tb2_fk foreign key (OrderNum) references tb1(OrderNum),
);

【问题讨论】:

  • 你应该添加参考REFERENCING OLD AS OLD
  • 嗨!非常感谢您的回复!我在删除 tb_1 之前执行了以下 CREATE OR REPLACE TRIGGER 触发器,每行都引用旧的但是,我仍然遇到同样的错误!

标签: oracle plsql


【解决方案1】:

关键字FETCH 应该是造成这种情况的原因,将其替换为BEGIN,这是正确的语法,

CREATE OR REPLACE TRIGGER trig
BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
INSERT INTO tb1 VALUES (:old.OrderNum, :old.Date,:old.CustomerName);
INSERT INTO tb2_arch VALUES (:old.OrderNum, :old.ItemNum, :old.Pieces);
DBMS_OUTPUT.PUT_LINE('Data archived.');
END;

编辑:您使用OLD 引用的列名可能无效,这就是此错误的原因。

触发器仅适用于 ONE 表的INSERT/UPDATE/DELETE 事件。不过,您可以在正文中引用多个表格。

OLDNEW 将始终引用您在DDL 中提到的表,例如DELETE ON tb1

以下修改后的代码会对您有所帮助。

CREATE OR REPLACE TRIGGER trig
BEFORE DELETE ON tb1 FOR EACH ROW
DECLARE
   v_ItemNum tb2.ItemNum%TYPE;
   v_Pieces tb2.Pieces%TYPE;
BEGIN
   INSERT INTO tb1_arch VALUES (:old.OrderNum, :old.Date,:old.CustomerName);

   /* Select the values for this item from table 2 */
   SELECT ItemNum,Pieces
    INTO v_ItemNum,v_Pieces
   FROM tb2
    WHERE OrderNum = :old.OrderNum;

   /* Insert the selected values in the table2's archive version */
   INSERT INTO tb2_arch VALUES (:old.OrderNum, v_ItemNum, v_Pieces);

   /* Delete the entry */
   DELETE from tb2 WHERE OrderNum = :old.OrderNum;

   DBMS_OUTPUT.PUT_LINE('Data archived.');
END;

或者,您可以使用另一个触发器 for delete on table2 并在那里存档数据。

【讨论】:

  • 您好,非常感谢您回复我的帖子!我按照你说的做了,还是一样的问题。是的,我的错误是 FETCH 不应该在那里。我首先尝试使用光标解决问题,但没有成功。
  • 否则列名Pieces应该是无效的。你能描述一下表tb_1吗?
  • 我就加在帖子里,方便大家阅读哈哈
  • 好的,所以pieces 列不存在?您使用OLD 引用它?
  • tb1 上不存在。 tb2 中存在“Pieces”列。而且我的代码有错字,应该是 tb1 而不是 tb_1(仍然是同样的错误)。
猜你喜欢
  • 2012-09-24
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 2019-06-05
  • 2017-08-16
  • 2015-08-09
  • 1970-01-01
  • 2020-10-22
相关资源
最近更新 更多