如何使用序列值将多行插入oracle?

时间:2008-10-23 01:39:42

标签: sql oracle

我知道如果我使用this answer中的语法,我可以使用单个语句插入多行。

但是,我插入的其中一个值来自序列,即

insert into TABLE_NAME
(COL1,COL2)
select MY_SEQ.nextval,'some value' from dual
union all
select MY_SEQ.nextval,'another value' from dual
;

如果我尝试运行它,我会收到ORA-02287错误。有什么方法可以解决这个问题,还是应该使用很多INSERT语句?

编辑:
如果我必须为序列之外的所有其他列指定列名,我将失去原有的简洁性,因此它不值得。在那种情况下,我将只使用多个INSERT语句。

6 个答案:

答案 0 :(得分:41)

这有效:

insert into TABLE_NAME (COL1,COL2)
select my_seq.nextval, a
from
(SELECT 'SOME VALUE' as a FROM DUAL
 UNION ALL
 SELECT 'ANOTHER VALUE' FROM DUAL)

答案 1 :(得分:24)

它不起作用,因为序列在以下场景中不起作用:

  • 在WHERE子句中
  • 在GROUP BY或ORDER BY子句中
  • 在DISTINCT条款中
  • 连同UNION或INTERSECT或MINUS
  • 在子查询中

来源:http://www.orafaq.com/wiki/ORA-02287

然而,这确实有效:

insert into table_name
            (col1, col2)
  select my_seq.nextval, inner_view.*
    from (select 'some value' someval
            from dual
          union all
          select 'another value' someval
            from dual) inner_view;

尝试一下:

create table table_name(col1 varchar2(100), col2 varchar2(100));

create sequence vcert.my_seq
start with 1
increment by 1
minvalue 0;

select * from  table_name;

答案 2 :(得分:4)

insert into TABLE_NAME
(COL1,COL2)
WITH
data AS
(
    select 'some value'    x from dual
    union all
    select 'another value' x from dual
)
SELECT my_seq.NEXTVAL, x 
FROM data
;

我认为这就是你想要的,但我现在无法访问oracle进行测试。

答案 3 :(得分:2)

来自Oracle Wiki,错误02287是

  

当您使用不允许的序列时,会发生ORA-02287。

在使用序列不能的地方,您似乎在尝试:

  

在子查询中

所以看来你不能在同一个声明中做多次。

他们提供的解决方案是:

  

如果要将序列值插入列中   对于创建的每一行,然后创建一个插入触发器和   获取触发器中的序列值并将其分配给列

答案 4 :(得分:1)

可能是在插入上创建一个触发器以添加正确的序列号。

答案 5 :(得分:0)

这有效,无需使用union all。

Insert into BARCODECHANGEHISTORY (IDENTIFIER,MESSAGETYPE,FORMERBARCODE,NEWBARCODE,REPLACEMENTDATETIME,OPERATORID,REASON)
select SEQ_BARCODECHANGEHISTORY.nextval, MESSAGETYPE, FORMERBARCODE, NEWBARCODE, REPLACEMENTDATETIME, OPERATORID, REASON
from (
  SELECT
    'BAR' MESSAGETYPE,
    '1234567890' FORMERBARCODE,
    '1234567899' NEWBARCODE,
    to_timestamp('20/07/12','DD/MM/RR HH24:MI:SSXFF') REPLACEMENTDATETIME,
    'PIMATD' OPERATORID,
    'CORRECTION' REASON
  FROM dual
);