Oracle触发器插入到其他表然后修改原始表

时间:2016-03-27 13:39:38

标签: oracle oracle11g triggers insert

我有两个表:

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更新为与序列上的主键值相同的值。
  4. 这是我的触发器的最新尝试:

    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. 创建一个处理插入和更新的过程。
    5. 任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:1)

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

要更改触发器中的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;
/

答案 1 :(得分:0)

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

另一种方法是创建'after statement'触发器,以使用适当的值更新ASSET_ENTRY_NOTE中的所有受影响的行。这些行将在行级触发器中收集,例如,包集合。

答案 2 :(得分:0)

我修好了它并且有效:

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