触发器不会将值插入另一个表中

时间:2017-03-08 11:50:23

标签: oracle triggers

我在后插入上写了<label [...]>&nbsp;Compare <input type="checkbox" aria-label="Select to add..."> </label> ,如下所示

但它没有插入表中。

1 个答案:

答案 0 :(得分:1)

您添加的插入语句的值为O之一(大写&#39; o&#39;字符);这需要是单引号中的字符串(即'O')或数字数字0(即0),具体取决于列数据类型。 (如果logtime是日期/时间戳字段,则字符串文字'15-04-14'也应该是实际日期 - 您可能依赖于隐式转换,这绝不是一个好主意。

但是,您的触发器仍会出现ORA-04091变异表错误,因为您的触发器插入是针对触发器所针对的同一个表的查询。您目前正在尝试将行FR_CITYSTATE_COM_DET插入LOGSAPDEALSLIPFUNDREQINTGRTN中的每行,这不太可能是您的意思。

你可能只想根据触发器实际触发的行在FR_CITYSTATE_COM_DET中插入一个新行,这意味着你应该使用values()子句而不是select,并且应该使用其中的:NEW伪记录值,即:

insert into fr_citystate_com_det (
  sapid,
  candidateid,
  city_name,
  city_code,
  r4g_state_name,
  r4g_state_code,
  statename,
  state_code,
  jc_id,
  area_code,
  system_date
)
values (
  :new.sapid,
  :new.candidateid,
  :new.city,
  :new.city,
  :new.state,
  :new.state,
  :new.state,
  :new.state,
  :new.jiocenter_id,
  :new.area_code,
  sysdate
);

使用基于插入的发明表结构进行演示:

create table logsapdealslipfundreqintgrtn(sapid varchar2(20), candidateid varchar2(20),
  companycode number, latitude number, longitude number, circle varchar2(20),
  state varchar2(20), city varchar2(20),address varchar2(12), rfsiteid varchar2(20),
  towertype varchar2(20), logtime varchar2(20), responsestring varchar2(20),
  logtype varchar2(20), towerht varchar2(20), transactionid varchar2(20),
  sapid_in_sap varchar2(20), nominal_sap_id varchar2(20), vendorcode varchar2(20),
  sitetype varchar2(20), jicenter_id varchar2(20), area_code varchar2(20),
  status varchar2(20), jiocenter_id varchar2(20));

create table fr_citystate_com_det(sapid varchar2(20), candidateid varchar2(20),
  city_name varchar2(20), city_code varchar2(20), r4g_state_name varchar2(20),
  r4g_state_code varchar2(20), statename varchar2(20), state_code varchar2(20),
  jc_id varchar2(20), area_code varchar2(20), system_date date);

create or replace trigger tr_fr_citystate_com_det after
  insert on logsapdealslipfundreqintgrtn
  for each row
begin
  if :new.responsestring like '%does not exists%'
  then
    insert into fr_citystate_com_det (
      sapid,
      candidateid,
      city_name,
      city_code,
      r4g_state_name,
      r4g_state_code,
      statename,
      state_code,
      jc_id,
      area_code,
      system_date
    )
    values (
      :new.sapid,
      :new.candidateid,
      :new.city,
      :new.city,
      :new.state,
      :new.state,
      :new.state,
      :new.state,
      :new.jiocenter_id,
      :new.area_code,
      sysdate
    );
  end if;
end;
/

Trigger TR_FR_CITYSTATE_COM_DET compiled

insert into LOGSAPDEALSLIPFUNDREQINTGRTN (SAPID,CANDIDATEID, companycode, latitude,
  longitude, circle, state, city,address, rfsiteid, towertype, logtime,
  responsestring, logtype, towerht, transactionid, sapid_in_sap, nominal_sap_id,
  vendorcode, sitetype, jiocenter_id, area_code, status)
values ('I-TN-DMPI-ENB-0010', 'C1', 5075, 12.15819,78.16203, 'TN', 'TN', 'DMPI',
  'Kovil Street', 'DMPI-RIL-0010', 'GBT', '15-04-14', 'does not exists', 'P1', 40,
  '130420215858576742', 'ITN-DMPI-ENB-0010', null, null, 'O', null, null, null);

1 row inserted.

select * from FR_CITYSTATE_COM_DET;

SAPID                CANDIDATEID          CITY_NAME            CITY_CODE            R4G_STATE_NAME       R4G_STATE_CODE       STATENAME            STATE_CODE           JC_ID                AREA_CODE            SYSTEM_DA
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- ---------
I-TN-DMPI-ENB-0010   C1                   DMPI                 DMPI                 TN                   TN                   TN                   TN                                                             08-MAR-17

如果您正在获取重复项并且想要在尝试时抛出异常,则可以在插入之前查询目标表以检查现有行:

...
for each row
declare
  l_count number;
begin
  if :new.responsestring like '%does not exists%'
  then
    select count(*) into l_count
    from fr_citystate_com_det
    where sapid = :new.sapid
    and candidateid = :new.candidateid
    and rownum = 1;

    if l_count > 0 then
      RAISE_APPLICATION_ERROR (-20000, 'Cannot insert duplicate SAPID and CANDIDATEID');
    end if;

    insert into fr_citystate_com_det (
    ...
    )
    values (
    ...
    );
  end if;
end;

如果sapid, candidateid上有唯一或主键,那么如果你试图插入副本,你会得到一个ORA-01001例外,但似乎你没有(来自评论/聊天) 。看起来他们应该形成一个键,如果你想要它们是唯一的。唯一的关键约束是强制唯一性的正确方法;不要复制内置功能。<​​/ p>

除了形成任何其他内容,如果两个会话同时插入相同的数据,它们将触发每个触发器,每个会看不到其他未决数据,因此将获得零计数,因此两者都将将新记录插入fr_citystate_com_det。使用约束可以避免这个问题。

如果列没有被编入索引,那么计数检查也可能很慢。

或者,正如我认为我在别处提到的那样,更改插入的任何过程并确定“不存在”&#39;需要值,并且两个插入,而不会将逻辑隐藏在触发器中。