我有一张桌子,人们一直在插入以获取主键
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,而是提示我输入它,这不是我需要的。
答案 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()来根据需要多次更改架构,即从某些愚蠢的更新脚本调用。