是否要创建存储的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;
这是实现这个目标的方法吗?
答案 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语句越少,代码执行得越好。