如何插入添加序列列的列?

时间:2016-07-02 01:53:28

标签: sql oracle plsql oracle11g

在Oracle数据库(11gR2)中,我有一个表my_table,其中包含列(序列 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次循环,就像逻辑上一样。如何通过添加序列列来实现预期目标并插入行?

4 个答案:

答案 0 :(得分:3)

不要在循环中这样做。只需使用row_number()

INSERT INTO my_table(seq, . . .)
     select row_number() over (order by NULL) - 1, . . .
     from . . .;

答案 1 :(得分:2)

显然,您应该使用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>;

序列号将连续插入。

答案 2 :(得分: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;

最后,执行insert,从序列加载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 :(得分:0)

所以,你已经有了表,它有所需的行数,现在你想在名为sequence的列中添加从0到总行数减1的数字? (也许不是“序列”,但不太可能与Oracle保留字冲突?)

然后这应该有效:

update my_table set seq = rownum - 1;