How can I insert multiple rows into oracle with a sequence value?

Viewed 164002

I know that I can insert multiple rows using a single statement, if I use the syntax in this answer.

However, one of the values I am inserting is taken from a sequence, i.e.

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

If I try to run it, I get an ORA-02287 error. Is there any way around this, or should I just use a lot of INSERT statements?

EDIT:
If I have to specify column names for all other columns other than the sequence, I lose the original brevity, so it's just not worth it. In that case I'll just use multiple INSERT statements.

6 Answers

This works:

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)

It does not work because sequence does not work in following scenarios:

  • In a WHERE clause
  • In a GROUP BY or ORDER BY clause
  • In a DISTINCT clause
  • Along with a UNION or INTERSECT or MINUS
  • In a sub-query

Source: http://www.orafaq.com/wiki/ORA-02287

However this does work:

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;

Try it out:

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

I think that is what you want, but i don't have access to oracle to test it right now.

From Oracle Wiki, error 02287 is

An ORA-02287 occurs when you use a sequence where it is not allowed.

Of the places where sequences can't be used, you seem to be trying:

In a sub-query

So it seems you can't do multiples in the same statement.

The solution they offer is:

If you want the sequence value to be inserted into the column for every row created, then create a before insert trigger and fetch the sequence value in the trigger and assign it to the column

A possibility is to create a trigger on insert to add in the correct sequence number.

Related