如何通过添加序列列插入列?
Posted
技术标签:
【中文标题】如何通过添加序列列插入列?【英文标题】:How to insert columns with adding sequence column? 【发布时间】:2016-07-02 01:53:27 【问题描述】:在 Oracle 数据库 (11gR2) 中,我有一个表 my_table
,其中包含列 (sequence、col1、col2、col3)。我想将值插入从其他表查询的表中,即insert into my_table select <query from other tables>
。问题是主键是四列,因此我需要添加一个从 0 开始直到要插入的行数的序列(顺序不是问题)。
我尝试使用这样的循环:
DECLARE
j NUMBER;
r_count number;
BEGIN
select count(1) into r_count from <my query to be inserted>;
FOR j IN 0 .. r_count
LOOP
INSERT INTO my_table
select <my query, incorporating r_count as sequence column> ;
END LOOP;
END;
但它不起作用,实际上循环r_count
次尝试每次插入整行,从逻辑上讲它应该这样做。如何通过添加序列列来实现预期目标并插入行?
【问题讨论】:
【参考方案1】:不要循环执行此操作。只需使用row_number()
:
INSERT INTO my_table(seq, . . .)
select row_number() over (order by NULL) - 1, . . .
from . . .;
【讨论】:
【参考方案2】:让我们用示例数据创建表(以模拟您的数据源)
-- This is your source query table (can be anything)
CREATE TABLE source_table
(
source_a VARCHAR(255),
source_b VARCHAR(255),
source_c VARCHAR(255)
);
insert into source_table (source_a, source_b, source_c) values ('A', 'B', 'C');
insert into source_table (source_a, source_b, source_c) values ('D', 'E', 'F');
insert into source_table (source_a, source_b, source_c) values ('G', 'H', 'I');
然后创建目标表,id 和 3 个数据列。
-- This is your target_table
CREATE TABLE target_table
(
id NUMBER(9,0),
target_a VARCHAR2(255),
target_b VARCHAR2(255),
target_c VARCHAR2(255)
);
-- This is sequence used to ensure unique number in 1st column
CREATE sequence target_table_id_seq start with 0 minvalue 0 increment BY 1;
最后,执行插入,从序列中加载id,从源表中加载其余数据。
INSERT INTO target_table
SELECT target_table_id_seq.nextval,
source_a,
source_b,
source_c
FROM source_table;
结果可能看起来像
1 A B C
2 D E F
3 G H I
如果您稍后添加一些值,它们将继续编号为 4、5、6 等。或者您只想在组内获得订单?因此,如果您再添加 2 行 JKL 和 MNO,目标表将如下所示
1 A B C
2 D E F
3 G H I
1 J K L
2 M N O
为此,您需要不同的解决方案(甚至不需要排序器)
SELECT
RANK() OVER (ORDER BY source_a, source_b, source_c),
source_a,
source_b,
source_c
FROM source_table;
从技术上讲,您可以直接使用 ROWNUM,但由于结果一致,我选择了 RANK() OVER 分析函数。请注意,如果您尝试两次插入相同的行,这将破坏您的复杂主键(我的第一个解决方案没有)
【讨论】:
【参考方案3】:显然,您应该使用 Oracle 序列。 首先,创建一个序列:
create sequence seq_my_table start with 0 minvalue 0 increment by 1;
然后使用它:
INSERT INTO my_table (sequence, ...)
select seq_my_table.nextval, <the rest of my query>;
序列号会连续插入。
【讨论】:
【参考方案4】:那么,您已经有了表,它具有所需的行数,现在您想在名为 sequence 的列中添加从 0 到总行数减一的数字? (也许不是“序列”,而是不太可能与 Oracle 保留字发生冲突的东西?)
那么这应该可以工作:
update my_table set seq = rownum - 1;
【讨论】:
不,我已经有了表格,但这些是我想插入的新行。我正在从其他几个表中检索并想添加一个序列。 ...但是您需要确保新数字不会与序列中已有的数字发生冲突? 你是对的。幸运的是,在这个特定的场景中 col1 是一个新的唯一值,只是针对这个特定的插入,所以其他序列不会因为它们有不同的 col1 而发生冲突。以上是关于如何通过添加序列列插入列?的主要内容,如果未能解决你的问题,请参考以下文章