【问题标题】:Oracle trigger insert to other table then modify the original tableOracle触发器插入到其他表然后修改原表
【发布时间】:2016-07-14 20:44:56
【问题描述】:

我有这两张表:

TABLE ASSET_ENTRY_NOTE (
  ID                  NUMBER         NOT NULL, --PK
  ASSETMDL_ID         NUMBER         NOT NULL, --FK
  DEPT_ID             NUMBER         NOT NULL, --FK
  LOCATION            NVARCHAR2(100) NOT NULL,
  ASSET_ID            NUMBER,                  --FK TO ASSETS
  ACCOUNT_ID          NUMBER         NOT NULL, --FK
  TOTAL_DPRC_DURATION FLOAT(126)     NOT NULL,
  TOTAL_PROD_HRS      FLOAT(126),
  AMORTIZATION_PRCNTG FLOAT(126),
  ACQUIRE_DATE        DATE           NOT NULL,
  DESCRIPTION         NVARCHAR2(200) NOT NULL,
  APPRFLAG            NUMBER         DEFAULT 0 NOT NULL,
  WRK_HRS             FLOAT(126),

)

TABLE ASSETS (
 ID                   NUMBER         NOT NULL, --PK
 ASSETMDL_ID          NUMBER         NOT NULL, --FK
 DEPT_ID              NUMBER         NOT NULL,
 LOCATION             NVARCHAR2(100) NOT NULL, --FK
 ACCOUNT_ID           NUMBER         NOT NULL,
 ACQUIRE_DATE         DATE           NOT NULL,
 TOTAL_DPRC_DURATION  FLOAT(126),
 BALANCE_CLOSING_DATE DATE,
 SELL_VAL             FLOAT(126),
 RPLCMNT_DISCOUNT     FLOAT(126),
 DESCRIPTION          NVARCHAR2(200) NOT NULL,
)

请注意,两个表之间存在一对一的关系(即ASSET_ENTRY_NOTE.ASSET_ID 是唯一的。 当ASSETS_ENTRY_NOTE.APPRFLAG 更新为 1 我有这个触发器:

  1. 获取ASSETS 表的新主键序列。
  2. 将数据从ASSETS_ENTRY_NOTE 插入到ASSETS
  3. ASSETS_ENTRY_NOTE.ASSET_ID 列更新为与序列中的主键值相同的值。

这是我的触发器的最新尝试:

CREATE OR REPLACE TRIGGER ENTRYNT_ASSET_TRIG
after UPDATE OF APPRFLAG ON ASSET_ENTRY_NOTE
  for each row
  when (new.apprflag = 1)
declare
   v_asset_id number;
BEGIN
 SELECT assets_PK_SEQ.NEXTVAL INTO v_asset_id   
  FROM DUAL d;

 insert into assets (ID,
                                    assets.assetmdl_id,
                                    assets.dept_id,
                                    assets.location,
                                    assets.account_id,
                                    assets.acquire_date,
                                    assets.total_dprc_duration,
                                    assets.description
                                    )

                           values (v_asset_id,
                                   assetmdl_id,
                                   dept_id,
                                   location,
                                   account_id,
                                   acquire_date,
                                   total_dprc_duration,
                                   description
                                   );

 update ASSET_ENTRY_NOTE set asset_id = v_asset_id where ;
END;

问题是,我知道ASSET_ENTRY_NOTE 是一个变异表,最后一个UPDATE 语句在这里是不允许的,但没有其他东西对我有用。 我已经尝试过的:

  1. 创建语句级触发器以仅更新一个值。
  2. 使用before 而不是after,但这是不正确的,因为我需要将值插入ASSETS
  3. 使用游标遍历每个更改的值,但我遇到了准确的提取错误。
  4. 创建处理插入和更新的过程。

任何帮助将不胜感激。

【问题讨论】:

    标签: oracle oracle11g triggers insert


    【解决方案1】:

    您必须将应用程序的设计更改为只有一个带有符号的表来指示特定实体的成员身份。

    另一种方法是创建“语句后”触发器,以使用正确的值更新 ASSET_ENTRY_NOTE 中所有受影响的行。这些行将被收集在例如行级触发器中的包收集中。

    【讨论】:

      【解决方案2】:

      这个设计对我来说似乎很奇怪,但要回答关于触发器的问题:

      要更改触发器中的asset_entry_note 行,您需要一个before update 触发器。在那里,您可以将值分配给 asset_id 列。

      您的insert 声明也是错误的。您可以在insert 语句的列列表中对列名进行表限定。 values 子句需要使用插入行中的值。您正在引用目标表的列,这是不允许的)。

      您也不需要select 语句来获取序列值。

      将所有这些放在一起,您的触发器应该如下所示:

      CREATE OR REPLACE TRIGGER ENTRYNT_ASSET_TRIG
      BEFORE UPDATE OF APPRFLAG ON ASSET_ENTRY_NOTE
        for each row
        when (new.apprflag = 1)
      declare
         v_asset_id number;
      BEGIN
        v_asset_id := assets_PK_SEQ.NEXTVAL;
      
        insert into assets 
          (ID,
           assetmdl_id,
           dept_id,
           location,
           account_id,
           acquire_date,
           total_dprc_duration,
           description)
         values 
           (v_asset_id,
            new.assetmdl_id, -- reference the inserted row here!
            new.dept_id,
            new.location,
            new.account_id,
            new.acquire_date,
            new.total_dprc_duration,
            new.description);
      
        new.asset_id := v_asset_id;
      END;
      /

      【讨论】:

      • 谢谢!我一找到答案就添加了答案,在这里,谢谢!!!!!!
      【解决方案3】:

      我修复了它并且它工作了:

      1. 已更改为before
      2. 将更新语句编辑为新的赋值,以便最后一行变为:new.asset_id := v_asset_id ;

      【讨论】:

        猜你喜欢
        • 2014-05-07
        • 1970-01-01
        • 2021-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        • 2019-01-04
        相关资源
        最近更新 更多