Автоинкрементные поля

jumperFF
Дата: 05.10.2004 03:20:49
Есть табличка с полем ID SERIAL NOT NULL.
В неё таким образом было вставлено 10 записей:
INSERT INTO User (ID, name) VALUES (1, 'Вася Пупкин');
INSERT INTO User (ID, name) VALUES (2, 'Степан Глюкавый');
...
Теперь, если я хочу добавить запись через
INSERT INTO User (name) VALUES ('Василий Тёркин');
PostgreSQL кричит
ERROR:  duplicate key violates unique constraint "user_pkey"
И кричит так пока я вставляю 10 раз новую запись, после этого начинает добавлять.
За сим вопрос, есть ли у PostgreSQL автоинкрементые поля что бы сами искали максимальный ID и начинали отсчёт с него?

Заранее спасибо.
PJD
Дата: 05.10.2004 04:54:35
Таких, чтобы делали все сами - нет. Нужно делать setval('sequence_name') после вставки вручную или в триггере на insert.
Примерно так (для восьмерки):
create table tuser(
  id serial primary key,
  name text
);

create or replace function fti_sequence_id() returns trigger as $_$
declare 
  v_seq_name text;
  v_id   int;
  v_curr int;
begin
  v_seq_name := TG_ARGV[1];
  v_id := NEW.id; --имя serial-поля - id
  begin
    v_curr := currval(v_seq_name);
  exception
    when OTHERS then v_curr := 0;
  end;
  --при одновременной явной вставке id из разных процессов будут проблемы
  if v_id > v_curr then
    raise notice 'setval(\'%\',%)', v_seq_name, v_id;
    perform setval(v_seq_name, v_id);
  end if;
  return NEW;
end;
$_$ language plpgsql;

create trigger ti_tuser_sequence after insert on tuser 
  for each row execute procedure fti_sequence_id('id', 'tuser_id_seq');


insert into tuser select 2, 'петров';
insert into tuser select 3, 'сидоров';
insert into tuser select s.i, 'кузнецов' from generate_series(4,10) s(i);
insert into tuser select 1, 'иванов';

insert into tuser (name) select 'козлов';
select currval('tuser_id_seq');