在 INSERT SELECT 语句期间生成增量数值列值
Posted
技术标签:
【中文标题】在 INSERT SELECT 语句期间生成增量数值列值【英文标题】:Generating incremental numeric column values during INSERT SELECT statement 【发布时间】:2011-02-15 04:14:39 【问题描述】:我需要在 Oracle 中将一些数据从一个表复制到另一个表,同时为新表中的数字列生成增量值。这是一个只有少量行数(100)的练习。
我对这个问题有足够的解决方案,但我很想知道是否有更优雅的方法。
我正在使用临时序列,如下所示:
CREATE SEQUENCE temp_seq
START WITH 1;
INSERT INTO new_table (new_col, copied_col1, copied_col2)
SELECT temp_seq.NEXTVAL, o.*
FROM (SELECT old_col1, old_col2
FROM old_table,
ORDER BY old_col1) o;
DROP SEQUENCE temp_seq;
有没有办法不创建序列或任何其他临时对象? 具体来说,这可以通过自包含的 INSERT SELECT 语句来完成吗?
请将触发器视为不可选项。
更多信息:我想控制插入新行的顺序,这与它们在旧表中创建的顺序不同(注意我添加了上面的 ORDER BY 子句)。但我仍然希望我的新顺序列从 1 开始。
有类似的问题,但我相信我的问题的细节是 SO 原创的。
【问题讨论】:
【参考方案1】:您可以使用ROWNUM
。这个伪列对结果中的行进行编号:
Insert Into new_table (new_col, copied_col1, copied_col2)
Select Rownum, old_col1, old_col2
From old_table;
如果您希望对记录进行排序,则需要使用子查询:
Insert Into new_table (new_col, copied_col1, copied_col2)
Select Rownum, old_col1, old_col2
From (
Select old_col1, old_col2
From old_table
Order By old_col1
);
【讨论】:
彼得,请参阅我添加的问题的附加条件。此方法似乎按照它们在旧表中创建的顺序插入行,但我想强制执行我自己的顺序。如果不是这个要求,你的方法将是完美的。有什么想法吗? @Charles:我的查询实际上不会对行进行排序,因此它们很可能是按照创建的顺序插入的(但不能保证)。您是否尝试将您的ORDER BY
应用于我的查询?我希望这能奏效。
然后将 ORDER BY 添加到 select 语句中。那应该可以得到你想要的。 ROWNUM 只是按检索顺序为记录生成一个序列号。
好吧,伙计们,你说对了一半。问题是在 ORDER BY 之前应用了 ROWNUM。解决方法是使用子查询。只需将我的解决方案中的 temp_seq.NEXTVAL 替换为 ROWNUM。瞧!彼得,因此更新您的答案,我会将其标记为已接受。谢谢!【参考方案2】:
为什么不将列 new_col 定义为 primary_key 或 unique 并将其标记为自动增量? 这样每个插入都会获得下一个更高的“计数”。
我对 oracle 不太熟悉,但我敢打赌有一个内置的自动增量功能。
【讨论】:
@Philipp Andre:没有自动增量功能,Oracle 使用序列代替。 @Peter Lang:真的吗?这让我感到惊讶,但很久以前我就玩过oracle。很高兴知道。谢谢! 现在您也可以在 Oracle 12c 中做到这一点:Identity Columns以上是关于在 INSERT SELECT 语句期间生成增量数值列值的主要内容,如果未能解决你的问题,请参考以下文章
高手,执行insert into select 语句慢,一般是啥原因造成的了
Hibernate 注解序列生成主键执行完select seq_t_user.nextval后不执行insert等语句导致 执行save()或update()方法无效
DataGrip 通过结果集生成insert into values语句