我有表foo
和PK int id
,varchar state
table foo:
- int id
- varchar state
- int code1
- int code2
如果记录不存在,我想执行sql插入操作。
要完成插入语句,我必须使用插入选择来检索一些信息。
在输入中,我有:
id = 1, state = 'A'
在插入中,我必须用插入选择检索到的值填充其他字段。
code1 and code2 where id = 1 (they are always the same for id = x)
通常我必须这样做:
1-使用where id=1 and state=1
进行选择,如果不存在,则必须执行sql插入
2-如果记录不存在,则检索字段code1 and code2 when id=1
3-插入
是否可以在一个查询中全部完成?
select * from foo where id=1 and state = 'A'
如果尚不存在:
select code1,code2 from foo where id=1; #1,2
insert into foo(id, state, code1, code2) values (1,'A', 1, 2);
是否可以在一个查询中合并?
谢谢
答案 0 :(得分:0)
您可以使用insert . . . select
:
insert into foo (id, some)
select 1, 'text'
from dual
where not exists (select 1 from foo where id = 1);
答案 1 :(得分:0)
为此,您可以使用* magical Oracle提示IGNORE_ROW_ON_DUPKEY_INDEX
。提示无提示地跳过重复的插入行-通常会导致`ORA-00001:违反唯一约束(...)。
我假设设置了以下表格:
create table foo
(id number not null,
status varchar2(1) not NULL,
code1 varchar2(10),
code2 varchar2(10));
alter table foo add (primary key (id, status));
insert into foo (id,status, code1,code2) values(1,'a','xxx', 'xxx');
insert into foo (id,status, code1,code2) values(1,'b','xxx', 'xxx');
insert into foo (id,status, code1,code2) values(2,'b','yyy', 'yyy');
commit;
因此,现在您要忽略状态为1
的记录中的2
来使用键code
进行插入,并使用键'b'
进行插入
这应该使您知道如何进行:
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX (foo (id, status)) */ into foo (id,status, code1,code2)
values( 1, 'a',
(select code1 from foo where id = 1 and status = 'b'),
(select code2 from foo where id = 1 and status = 'b'));
0 rows created.
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX (foo (id, status)) */ into foo (id,status, code1,code2)
values( 2, 'a',
(select code1 from foo where id = 2 and status = 'b'),
(select code2 from foo where id = 2 and status = 'b'));
1 rows created.
根据需要调整子查询以获取code1
和code2
-您可以使用max(code1)
并忽略status
。
使用绑定变量在查询中传递id
(三次)。
答案 2 :(得分:0)
在表中,id
是主键。因此,如果您尝试插入具有现有id
的行,则oracle将引发错误。
您可以根据需要处理该错误。
但是,如果您“确实”要在插入之前进行检查,则可以尝试使用PL / SQL块。
declare
_id INTEGER
begin
SELECT id into _id from foo;
exception
when NO_DATA_FOUND then
insert into foo(id,some) values (1,'text');
end;
/
注意:请确保在结尾加上/。这将运行您的PL / SQL块。
基本上,此块尝试选择具有给定id
的行。如果存在,则只需正常结束该块。如果没有返回任何行,则这是该块的“例外”,您可以通过插入所需的内容来“处理”它。
begin
insert into foo(id,some) values (1,'text');
exception
when DUP_VAL_ON_INDEX then
DBMS_OUTPUT.PUT_LINE('Already exists');
end;
/
注意::如果要查看PL / SQL块的任何输出,则可能需要执行
set serveroutput on;
在运行任何PL / SQL块之前。
希望这会有所帮助。
答案 3 :(得分:0)
在Oracle中的单个语句中执行此操作的方法是use the MERGE statement。对于您而言,您可以执行以下操作:
MERGE INTO FOO
USING (SELECT f.ID,
'A' AS STATE,
f.CODE1,
f.CODE2
FROM FOO f
WHERE f.ID = 1) d
ON (d.ID = FOO.ID AND
d.STATE = FOO.STATE)
WHEN NOT MATCHED THEN INSERT
(ID, STATE, CODE1, CODE2)
VALUES
(d.ID, d.STATE, d.CODE1, d.CODE2)
好运。