【问题标题】:PLS-00049: bad bind variable 'NEW.REQUEST_DATETIME' IssuePLS-00049:错误的绑定变量“NEW.REQUEST_DATETIME”问题
【发布时间】:2016-01-03 19:21:18
【问题描述】:

我正在尝试编写一个触发器,它基本上会在另一个表上创建条目时更新一个表。

CREATE OR REPLACE TRIGGER "DTISCDB_OWNER"."REQUEST_CONTEXT_TR" 
AFTER INSERT OR UPDATE ON REQUEST_CONTEXT 
FOR EACH ROW
BEGIN
:NEW.REQUEST_DATETIME := SYSDATE;
:NEW.ID := TRUNC(DBMS_RANDOM.VALUE(100000000000000000000000000000000000,999999999999999999999999999999999999));
SELECT bre_conditions_seq.NEXTVAL INTO :OLD.seq_number FROM dual;
SELECT REQUEST_CONTEXT.CURRENT_STATE INTO :NEW.STATE FROM REQUEST_CONTEXT;
SELECT REQUEST_CONTEXT.REQUEST_ID INTO :NEW.REQUEST_ID FROM REQUEST_CONTEXT;

INSERT INTO REQUEST_LIFECYCLES(ID,SEQ_NUMBER,STATE,REQUEST_ID,REQUEST_DATETIME)
                        VALUES(:NEW.ID,:NEW.seq_number,:NEW.STATE,:NEW.REQUEST_ID,:NEW.REQUEST_DATETIME);
 END;

【问题讨论】:

  • 这个错误似乎暗示request_context中没有request_datetime。有没有?一旦你解决了这个问题,你就不能改变:old.seq_number,这样就没有意义了。您不能从 request_context 中选择。为什么要生成一个随机数而不是仅仅使用一个序列来生成:new.id
  • 您是否尝试使用:NEW 来引用您要插入的表中的列,而不是触发器所针对的表?您可以直接在values 子句中使用sysdate:OLD 参考仍然令人困惑。你似乎对新旧代表什么感到困惑。

标签: sql oracle11g triggers


【解决方案1】:

您似乎对correlation pseudorows 的用途以及它们拥有和可以做什么感到困惑。看起来您将 :NEW 视为与您在触发器内插入的 REQUEST_LIFECYCLES 表相关,而将 :OLD 视为与已插入或更新的 REQUEST_CONTEXT 行相关并导致触发器触发。

OLDNEW 都引用了触发器所针对的表,REQUEST_CONTEXT。如果触发器由更新触发,则OLD 具有受影响行的更新前值;如果它是由插入触发的,那么它是空的,因为没有旧状态。无论哪种方式,NEW 都具有当前状态,具有新插入或更新后的值。您无法更改 OLD 值,并且在“之后”触发器中更改 NEW 值没有意义。您也不需要查询触发触发器的表,因为 NEW 伪行已经提供了该信息。

因此,如果您尝试使用 REQUEST_CONTEXT 中插入/更新的值在 REQUEST_LIFECYCLES 中创建一行,您可以执行以下操作:

CREATE OR REPLACE TRIGGER "DTISCDB_OWNER"."REQUEST_CONTEXT_TR" 
AFTER INSERT OR UPDATE ON REQUEST_CONTEXT 
FOR EACH ROW
BEGIN
  INSERT INTO REQUEST_LIFECYCLES(ID, SEQ_NUMBER, STATE, REQUEST_ID,
    REQUEST_DATETIME)
  VALUES(TRUNC(DBMS_RANDOM.VALUE(100000000000000000000000000000000000, 999999999999999999999999999999999999)),
    bre_conditions_seq.NEXTVAL, :NEW.CURRENT_STATE, :NEW.REQUEST_ID,SYSDATE);
END;
/

我假设您想从触发器设置“生命周期”SEQ_NUMBER 值,尽管您尝试设置 :OLD 值 - 希望旧参考是一个错误。如果您尝试在REQUEST_CONTEXTREQUEST_LIFECYCLES 中设置该值,则需要一个插入/更新前触发器,并在values 中使用它之前设置:NEW.SEQ_NUMBER 而不是:OLD 值子句。

正如贾斯汀所说,对 ID 使用随机值是相当奇怪的,尤其是因为它不会是唯一的,而且序列更为常见。您实际上可能需要插入/更新行中的 ID,在这种情况下,您可以在 values 子句中引用 :NEW.ID 而不是生成新值。 (您也可能尝试在REQUEST_CONTEXTREQUEST_LIFECYCLES设置该ID,但这会更奇怪,您需要一个插入前/更新触发器来执行无论如何)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2019-06-05
    • 2017-08-16
    • 2015-08-09
    • 1970-01-01
    • 2020-10-22
    • 2022-06-13
    相关资源
    最近更新 更多