插入带有序列的两个oracle表

时间:2013-06-12 07:21:55

标签: sql oracle

我在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做到这一点。

4 个答案:

答案 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 Fiddle

来自限制:

  

您无法在多表插入的任何部分中指定序列   声明。多表插入被视为单个SQL语句。   因此,对NEXTVAL的第一次引用会生成下一个数字,   并且语句中的所有后续引用都返回相同的数字。

显然我在values子句中使用了一个序列,所以第一句似乎不太准确;但你不能在select部分使用它。 (我不是100%确定它是否可以在所有版本的values中使用,但文档在任何情况下都有点误导,并且与自身相矛盾。)

所以我利用了这样一个事实,因为它是一个单一的语句,对nextval的两个引用得到的数字与第三个句子相同,所以在两个表中使用相同的序列值

答案 1 :(得分:2)

您可以使用jobidsequence.currval获取序列的当前值(在一个会话事务中,即在COMMIT 之前,当您之前调用nextval时,直到再次致电nextval

请参阅:Oracle Admin Manual: Managing Sequences

答案 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;