根据员工是否存在于表中进行更新或插入

时间:2012-03-19 11:30:50

标签: oracle stored-procedures

是否要创建存储的procc,如果表中不存在当前行,则根据条件更新或插入表中?

这是我到目前为止所提出的:

PROCEDURE SP_UPDATE_EMPLOYEE
(
   SSN                              VARCHAR2,
   NAME                             VARCHAR2
)
AS
BEGIN
    IF EXISTS(SELECT * FROM tblEMPLOYEE a where a.ssn = SSN)
     --what ? just carry on to else
    ELSE
    INSERT INTO pb_mifid (ssn, NAME)
     VALUES (SSN, NAME);
END;

这是实现这个目标的方法吗?

2 个答案:

答案 0 :(得分:2)

BEGIN
  INSERT INTO pb_mifid (ssn, NAME)
  select  SSN, NAME from dual
  where not exists(SELECT * FROM tblEMPLOYEE a where a.ssn = SSN);
END;

<强>更新 注意,您应该将参数命名为p_ssn(区分SSN列),查询将变为:

  INSERT INTO pb_mifid (ssn, NAME)
  select  P_SSN, NAME from dual
  where not exists(SELECT * FROM tblEMPLOYEE a where a.ssn = P_SSN);

因为这总是存在:

SELECT * FROM tblEMPLOYEE a where a.ssn = SSN 

答案 1 :(得分:2)

这是一种非常常见的模式。根据您运行的Oracle版本,您可以使用merge语句(我不确定它出现在哪个版本中)。

create table test_merge (id integer, c2 varchar2(255));

create unique index test_merge_idx1 on test_merge(id);

merge into test_merge t
  using (select 1 id, 'foobar' c2 from dual) s
  on (t.id = s.id)
  when matched then update set c2 = s.c2
  when not matched then insert (id, c2) 
  values (s.id, s.c2);

合并旨在合并源表中的数据,但您可以通过从双重数据中选择数据来伪造它。

如果您无法使用合并,则针对最常见的情况进行优化。 proc会不会找到记录并需要插入记录,还是通常需要更新现有记录?

如果插入最常见,则以下代码可能是最好的:

begin
  insert into t (columns) 
  values ()
exception
  when dup_val_on_index then
    update t set cols = values
end;

如果更新是最常见的,请转过程:

begin
  update t set cols = values;

  if sql%rowcount = 0 then  
    -- nothing was updated, so the record doesn't exist, insert it. 
    insert into t (columns)
            values ();
  end if;
end;

你不应该发出一个选择来检查行并根据结果做出决定 - 这意味着你总是需要运行两个SQL语句,当你可以在大多数情况下逃脱时(或者总是如果你使用合并)。您使用的SQL语句越少,代码执行得越好。