什么数据类型是:OLD和:触发器中的新变量?

Ada*_*ter 6 sql oracle triggers

假设您有一个触发器,MY_CUSTOMER_TABLE并且它有一个声明为type的变量MY_CUSTOMER_TABLE%ROWTYPE.如何将OLD值分配给该变量?

CREATE TRIGGER CUSTOMER_BEFORE
  BEFORE UPDATE ON MY_CUSTOMER_TABLE
  FOR EACH ROW
DECLARE
  old_version MY_CUSTOMER_TABLE%ROWTYPE;
BEGIN
  old_version := :OLD; /* Causes a PLS-00049 bad bind variable 'OLD' */
  old_version := OLD;  /* Causes a PLS-00201 identifier 'OLD' must be declared */
END;
Run Code Online (Sandbox Code Playgroud)

编辑:

为了澄清,这是约,因为我使用触发器从归档行MY_CUSTOMER_TABLEMY_CUSTOMER_TABLE_HISTORY.根据不同的行动正在执行(INSERT,UPDATE,DELETE),我需要从任的所有字段OLDNEW:

CREATE TRIGGER CUSTOMER_BEFORE
  BEFORE UPDATE ON MY_CUSTOMER_TABLE
  FOR EACH ROW
DECLARE
  historical_record MY_CUSTOMER_TABLE_HISTORY%ROWTYPE;

  PROCEDURE
    copy
    (
      source_record      MY_CUSTOMER_TABLE%ROWTYPE,
      destination_record IN OUT MY_CUSTOMER_TABLE_HISTORY%ROWTYPE
    )
  BEGIN
    destination_record.customer_id   := source_record.customer_id;
    destination_record.first_name    := source_record.first_name;
    destination_record.last_name     := source_record.last_name;
    destination_record.date_of_birth := source_record.date_of_birth;
  END;

BEGIN
  /* I didn't want to replicate the same assignment statements for 
     each of the two cases: */
  CASE
    WHEN INSERT OR UPDATING THEN
      copy( source_record => :NEW, destination_record => historical_record );

    WHEN DELETING THEN
      copy( source_record => :OLD, destination_record => historical_record );

  END CASE;

  /* Some other assignments to historical_record fields... */

  INSERT INTO MY_CUSTOMER_TABLE_HISTORY VALUES historical_record;
END;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,PL/SQL不会让我传递:OLD或者:NEW是一个需要MY_CUSTOMER_TABLE%ROWTYPE参数的过程.

小智 1

据我所知, :NEW 和 :OLD 的定义有点模糊。我看到它被称为对“伪记录”的引用。不过,Oracle 似乎不是在行类型中设置每列都可引用的实际行类型,而是为每个单独的列设置一个引用,然后您可以使用 :NEW 和 :OLD 来引用该列。但是,正如您所发现的, :NEW 和 :OLD 本身似乎不可引用。

例如,这里. (是的,我知道,这是一个 Java 参考,但请参阅有关 :OLD 本身不是有效参考的评论。

我还发现这个注释SYS.DBMS_DEBUG包意味着 :NEW/:OLD 也不是有效的绑定。

-- get_value 和 set_value 现在支持绑定名称。绑定名称必须用引号括起来并大写。请注意,触发器绑定具有 -- 限定名称,即“:NEW”不是有效绑定,而“:NEW.CLMN” -- 是有效的。

使用触发器的建议AFTER您有用吗?从您的示例来看,似乎没有对值进行任何验证(意识到为了简单起见您可能没有将其放入示例中)。

我试图设想一种方法来动态构建一个公共类型(在触发器内),该类型将使用 all_tab_columns 视图匹配您的表行类型,然后将所有值填充到其中,但无法完全理解如果它能起作用的话,它可能会如何发生变化的细节。最终可能会比记录历史记录所需的工作量更多!