我在Oracle中有两个表,作业和参考。
我想在两个表中插入一条新记录,并使用从序列生成的密钥。类似的东西:
insert into (
select j.jobid, j.fileid, j.jobname, r.reffileid
from job j
inner join reference r on j.jobid=r.jobid)
values (jobidsequence.nextval, 4660, 'name', 4391);
这当然会导致:
ORA-01776: cannot modify more than one base table through a join view
有没有办法在不使用PL / SQL的情况下执行此操作?我非常喜欢只用SQL做到这一点。
答案 0 :(得分:11)
您可以使用insert all
multi-table insert语法的副作用:
insert all
into job (jobid, fileid, jobname)
values (jobidsequence.nextval, fileid, jobname)
into reference (jobid, reffileid)
values (jobidsequence.nextval, reffileid)
select 4660 as fileid, 'name' as jobname, 4391 as reffileid
from dual;
2 rows inserted.
select * from job;
JOBID FILEID JOBNAME
---------- ---------- ----------
42 4660 name
select * from reference;
JOBID REFFILEID
---------- ----------
42 4391
来自限制:
您无法在多表插入的任何部分中指定序列 声明。多表插入被视为单个SQL语句。 因此,对NEXTVAL的第一次引用会生成下一个数字, 并且语句中的所有后续引用都返回相同的数字。
显然我在values
子句中使用了一个序列,所以第一句似乎不太准确;但你不能在select
部分使用它。 (我不是100%确定它是否可以在所有版本的values
中使用,但文档在任何情况下都有点误导,并且与自身相矛盾。)
所以我利用了这样一个事实,因为它是一个单一的语句,对nextval
的两个引用得到的数字与第三个句子相同,所以在两个表中使用相同的序列值
答案 1 :(得分:2)
您可以使用jobidsequence.currval
获取序列的当前值(在一个会话事务中,即在之前,当您之前调用COMMIT
nextval
时,直到再次致电nextval
。
答案 2 :(得分:0)
更简单的方式..
begin
insert into job (
col1,
...
coln)
select
col1,
....
coln
from
tableA
<condition>;
insert into job2 (
col1,
...
coln)
select
col1,
....
coln
from
tableB
<condition>;
End;
答案 3 :(得分:0)
试试这样:
PROCEDURE ADD_CAMPAIGN (
configXML IN CLOB
) IS
vn_CAMPAIGNID number;
BEGIN
vn_CAMPAIGNID := CAMPAIGN_SEQUENCE.NEXTVAL;
INSERT INTO CAMPAIGN_INFO (campaign_id,name,start_date,period,handset_statu,bscs_service_id)
VALUES(vn_CAMPAIGNID ,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/name/text()').getStringVal() ,
TO_DATE(XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/startDate/text()').getStringVal()) ,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/period/text()').getNumberVal() ,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/handsetStatu/text()').getStringVal(),
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/bscsServiceID/text()').getNumberVal()
);
INSERT INTO PROMO_INFO(CAMPAIGN_ID,NAME)
VALUES(vn_CAMPAIGNID,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/promoName/text()').getStringVal());
INSERT INTO UTILITY_INFO(CAMPAIGN_ID,NAME)
VALUES(vn_CAMPAIGNID,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/utilityName/text()').getStringVal()) ;
INSERT INTO FREE_UNIT_INFO(CAMPAIGN_ID,NAME)
VALUES(vn_CAMPAIGNID,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/packageName/text()').getStringVal()) ;
INSERT INTO HANDSET_INFO(HANDSET_ID,NAME,CAMPAIGN_ID)
VALUES(HANDSET_SEQUENCE.NEXTVAL,
XMLTYPE(configXML).EXTRACT('/campaign/campaignInfo/handsetName/text()').getStringVal(),
vn_CAMPAIGNID);
END ADD_CAMPAIGN;