Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 触发器没有将值插入到另一个表中_Oracle_Triggers - Fatal编程技术网

Oracle 触发器没有将值插入到另一个表中

Oracle 触发器没有将值插入到另一个表中,oracle,triggers,Oracle,Triggers,我在插入后在上写了一个触发器,如下所示 但是它不会被插入到表中。您添加的insert语句有一个值为O(大写的“O”字符);根据列数据类型,它需要是单引号中的字符串(即'O')或数字零(即0)。(如果logtime是一个日期/时间戳字段,字符串literal'15-04-14'也应该是一个实际日期-您可能依赖于隐式转换,这从来都不是一个好主意) 但是,您的触发器仍然会得到ORA-04091突变表错误,因为您的in触发器插入基于对触发器所针对的同一个表的查询。您当前正在尝试为logsapdaleli

我在插入后在上写了一个
触发器
,如下所示


但是它不会被插入到表中。

您添加的insert语句有一个值为
O
(大写的“O”字符);根据列数据类型,它需要是单引号中的字符串(即
'O'
)或数字零(即
0
)。(如果
logtime
是一个日期/时间戳字段,字符串literal
'15-04-14'
也应该是一个实际日期-您可能依赖于隐式转换,这从来都不是一个好主意)

但是,您的触发器仍然会得到ORA-04091突变表错误,因为您的in触发器插入基于对触发器所针对的同一个表的查询。您当前正在尝试为
logsapdalelipfundrequintgrtn
中的每一行将行插入
FR\u CITYSTATE\u COM\u DET
,这不太可能是您的意思

您可能只想根据触发器实际触发的行在
FR\u CITYSTATE\u COM\u 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异常,但您似乎没有(从评论/聊天中)。如果你想让它们独一无二,它们似乎应该成为一把钥匙。唯一键约束是强制唯一性的正确方法;不要复制内置功能

除此之外,如果两个会话同时插入相同的数据,它们将各自触发触发器,每个会话都看不到另一个的挂起数据,因此计数为零,因此两者都将将新记录插入
fr\u citystate\u com\u det
。使用约束可以避免这个问题

如果列根本没有索引,那么计数检查也可能很慢


或者,正如我在其他地方提到的,更改插入的任何进程,并确定需要“不存在”值,并让该进程同时执行这两个插入,而不在触发器中隐藏逻辑。

Mysql或Oracle?@Aleksej:我使用的是
Oracle SQL developer
。@vvv你可能是,但这仍然不能回答问题-您正在使用的数据库平台是什么?MySQL与Oracle是不同的RDBMS。@Boneist:好的,我使用的是Oracle。你能编辑这个问题以包含实际使用的insert语句吗?此外,是否确实要在每次插入“不存在”行时,将LOGSAPDEALSLIPFUNDREQINTGRTN中每一行的数据插入FR_CITYSTATE_COM_DET?或者您真的只想复制新插入行中的数据吗?嗨,这段代码中的Alex。我不希望用户为相同的
sapid
candidateid
插入重复记录。如何预防?这又回到了“不存在”值是如何被放在第一位的;还有(也许)如果你也把它作为更新后的触发器。您可以执行查询以统计具有新sapid/candiateid的行数,并且仅在该行数为零时插入;或者将插入更改回
insert。。。从dual中选择
but,并在不存在的地方添加一个检查新值不存在的子句。确定。我想这似乎是新的东西。我应该问新问题还是只在这里更新?。如果可能的话,请在这里聊天@vvv-是的,可能应该是一个新问题,尽管可能太广泛了,并且有很多关于如何避免重复的例子。我已经为这个答案添加了一些例子。我现在有两个if条件,你可以在聊天中看到我更新的触发器。让我知道可以吗