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

Posted

技术标签:

【中文标题】如何使用序列值将多行插入到 oracle 中?【英文标题】:How can I insert multiple rows into oracle with a sequence value? 【发布时间】:2008-10-23 01:39:41 【问题描述】:

我知道如果我使用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 语句。

【问题讨论】:

如果您来到这里并且只想在同一个查询中选择多个不同的唯一序列 nextval,请参阅 ***.com/questions/8292199/…... 【参考方案1】:

这行得通:

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)

【讨论】:

收到以下错误:java.sql.BatchUpdateException: ORA-02287: sequence number not allowed here @beckah 提出一个新问题,显示您的 SQL 和 Oracle 版本? 想通了!将插入的序列值构造为查询而不是简单地将'sequencer.nextval'构造为插入值效果很好:) @WW【参考方案2】:

它不起作用,因为序列在以下情况下不起作用:

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

【讨论】:

【参考方案3】:
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 来测试它。

【讨论】:

这需要什么版本的 Oracle?【参考方案4】:

来自Oracle Wiki,错误02287是

当您使用不允许的序列时会出现 ORA-02287。

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

在子查询中

所以看来你不能在同一个语句中做多个。

他们提供的解决方案是:

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

【讨论】:

我以前做过。这是一种痛苦,但似乎是唯一的解决方法。【参考方案5】:

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

【讨论】:

【参考方案6】:

这行得通,不需要使用 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
);

【讨论】:

真的吗?如果不使用联合,如何在单个语句中插入多行?

以上是关于如何使用序列值将多行插入到 oracle 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在oracle 11g中使用一个INSERT语句在一列中插入多行[重复]

如何使用 SQL 或 PLSQL 将多行数据插入 Oracle 中的表中?

使用select将多行插入表中,但是表在oracle SQL中具有主键[重复]

如何复制多行(Oracle)

如何使用查找的值将记录插入 SQL?

使用序列设置主 ID 时如何将数据批量插入表中