在现有表上使用序列

时间:2010-03-01 19:18:09

标签: sql oracle sequence

我有一张桌子,人们一直在插入以获取主键

SELECT max(id)+1 from table_a;

我想使用INSERT INTO table_a SELECT ... FROM table_b, table_c ...简单的SQL脚本向该表添加一些记录,我想知道如何生成主键。我的第一个想法是创建一个临时序列,但Oracle显然没有select setval来设置第一个值。那么如何获得max(id)+1的当前值来为我的序列设置“start with”参数?

我在网上找到了一些我觉得可行的东西:

COLUMN S new_value st select max(id)+1 S from  table_a;
CREATE SEQUENCE cra_seq start with &st;

但它实际上并没有使用CREATE SEQUENCE中的st,而是提示我输入它,这不是我需要的。

4 个答案:

答案 0 :(得分:3)

这是你想要的吗?

  1  declare
  2    id  integer;
  3  begin
  4    select max(rownum)+1 into id from dual;
  5    execute immediate 'create sequence myseq start with '||TO_CHAR(id);
  6* end;
  7  /

答案 1 :(得分:1)

你不能像这样使用row_number函数:

Insert Destination( Id, ...)
Select row_number() over( order by TableA.Col1... ) + MaxDestination.MaxId + 1 Num
 , ....
From TableA, TableB,...
 Cross Join ( Select Max(Id) MaxId From Destination ) MaxDestination

答案 2 :(得分:0)

您可以使用row_number analytical function生成行号(1到N)。

在执行插入操作之前,获取表中的最大ID,然后将行号添加到该最大值,它将正确填充表。

答案 3 :(得分:0)

在PostgreSQL中:

CREATE SEQUENCE new_seq;
ALTER TABLE existing_table ADD COLUMN new_serial_column bigint DEFAULT 0;
UPDATE existing_table SET new_serial_column = nextval('new_seq');
ALTER TABLE existing_table ALTER COLUMN new_serial_column SET NOT NULL;
ALTER TABLE existing_table ALTER COLUMN new_serial_column SET DEFAULT nextval('new_seq');

虽然,该代码不是幂等的,所以检查你还没有创建新的序列,如:

CREATE FUNCTION fixup_existing_table() RETURNS void AS $$
DECLARE
    new_id bigint;
    seq_column_exists integer;
BEGIN
    SELECT Count(column_name) INTO seq_column_exists FROM information_schema.columns WHERE table_name='existing_table' and column_name='new_serial_column';
IF seq_column_exists != 0 THEN RETURN; END IF;

    CREATE SEQUENCE new_seq;
    ALTER TABLE existing_table ADD COLUMN new_serial_column bigint DEFAULT 0;
    UPDATE existing_table SET new_serial_column = nextval('new_seq');
    ALTER TABLE existing_table ALTER COLUMN new_serial_column SET NOT NULL;
    ALTER TABLE existing_table ALTER COLUMN new_serial_column SET DEFAULT nextval('new_seq');
END;
$$ LANGUAGE plpgsql;

然后,您可以安全地调用:SELECT fixup_existing_table()来根据需要多次更改架构,即从某些愚蠢的更新脚本调用。