Генерация postgreSQL uuid

select uuid_generate_v4() as one, uuid_generate_v4() as two;

"один" uuid и "два" uuid равны!

CREATE TABLE "TB"
(
  "Id" uuid NOT NULL DEFAULT uuid_generate_v4(),
  "Title" character varying NOT NULL,
   CONSTRAINT "TB_Class_ID" PRIMARY KEY ("Id")
);

postgresql 9.0 pgAdmin 1.12.3

insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');
insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');
insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');

или

insert into "TB" ("Title") values ('111');
insert into "TB" ("Title") values ('111');
insert into "TB" ("Title") values ('111');

результат:

ERROR:  duplicate key value violates unique constraint "TB_Class_ID"
DETAIL:  Key ("Id")=(12ab6634-995a-4688-9a9a-ee8c3fe24395) already exists.

тогда

postgreSQL maestro 9.2.0.4

insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');
insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');
insert into "TB" ("Id", "Title") values (uuid_generate_v4(), '111');

результат: пострадали 1 строка;

Я понимаю, что maestro добавляет записи один за другим, но почему uuid_generate_v4() возвращает одно и то же значение после двух вызовов? (В случае pgAdmin).

И как я могу добавить несколько строк по одному запросу?

Ответ 1

В рамках данной транзакции функция uuid_generate_v4() возвращает одно и то же значение.

Когда операторы сгруппированы и выполняются как "одна команда", есть одна транзакция, поэтому каждый вызов uuid_generate_v4() будет возвращать то же значение.

Два способа "исправить":

  • Выполнять отдельные вызовы базы данных каждый раз, когда вы используете эту функцию (это проще всего)
  • Используйте соединение без автосохранения, в котором вы контролируете транзакции и разделяете каждое использование в паре BEGIN; COMMIT (это проблема - не делайте этого, если вам не нужно)

Ответ 2

В какой-то момент в прошлом функции uuid_generate_* были ошибочно отмечены как IMMUTABLE, что привело бы к поведению, которое вы показываете. Это было исправлено во всех последних версиях, но вам нужно повторно запустить установку script (uuid-ossp.sql), чтобы получить обновленные определения функций. (Вы также можете изучить установку script, чтобы убедиться, что у вас есть обновленная версия. Функции должны быть отмечены VOLATILE.)

Ответ 3

Чтобы избежать дубликатов, вы можете использовать генерацию следующим образом:

select md5(random()::text || clock_timestamp()::text)::uuid AS new_id, id from table;

Но будьте осторожны: это генерирует UUID, но это не UUIDv4. Подробнее: Генерация UUID в Postgres для оператора вставки?

Ответ 4

begin ISOLATION LEVEL READ UNCOMMITTED;
insert into "TB" ("Title") values ('111');
insert into "TB" ("Title") values ('111');
insert into "TB" ("Title") values ('111');
commit;

возможно тоже