Я использую postgres 9.4; У меня есть таблица с уникальным индексом. Я хотел бы изменить имя, добавив суффикс, чтобы гарантировать уникальность имени.postgresql trigger, чтобы сделать имя уникальным
Я создал триггер «до», который вычисляет суффикс. Он хорошо работает в автоматическом режиме. Однако, если два объекта с одинаковым именем вставляются в одну транзакцию, они получают одинаковый уникальный суффикс.
Каков наилучший способ выполнить мою задачу? Есть ли способ справиться с ним с помощью триггера, или я должен ... hmm ... обернуть вставку или обновление в точку сохранения, а затем обработать ошибку?
UPDATE (вос комментарий от @Haleemur Али):
Я не думаю, что мой вопрос зависит от деталей. Существенным моментом является то, что я запрашиваю подмножество коллекции, над которой я хочу применить уникальность, и выберем новое имя ... однако, казалось бы, когда запросы выполняются на двух объектах, одинаково названных в одной транзакции, никто не видит изменения других для нового значения.
Но ... на всякий случай ... мой триггер содержит ("тип" фиксирован параметр функции запуска):
select find_unique(coalesce(new.name, capitalize(type)),
'vis_operation', 'name', format(
'sheet_id = %s', new.sheet_id)) into new.name;
Где "find_unique" содержит:
create or replace function find_unique(
stem text, table_name text, column_name text, where_expr text = null)
returns text language plpgsql as $$
declare
table_nt text = quote_ident(table_name);
column_nt text = quote_ident(column_name);
bstem text = replace(btrim(stem),'''', '''''');
find_re text = quote_literal(format('^%s((\d+$)|$)', bstem));
xtct_re text = quote_literal(format('^(%s ?)', bstem));
where_ext text = case when where_expr is null then '' else 'and ' || where_expr end;
query_exists text = format(
$Q$ select 1 from %1$s where btrim(%2$s) = %3$s %4$s $Q$,
table_nt, column_nt, quote_literal(bstem), where_ext);
query_max text = format($q$
select max(coalesce(nullif(regexp_replace(%1$s, %4$s, '', 'i'), ''), '0')::int)
from %2$s where %1$s ~* %3$s %5$s
$q$,
column_nt, table_nt, find_re, xtct_re, where_ext);
last int;
i int;
begin
-- if no exact match, use exact
execute query_exists;
get diagnostics i = row_count;
if i = 0 then
return coalesce(bstem, capitalize(right(table_nt,4)));
end if;
-- find stem w/ number, use max plus one.
execute query_max into last;
if last is null then
return coalesce(bstem, capitalize(right(table_nt,4)));
end if;
return format('%s %s', bstem, last + 1);
end;
$$;
пример кода вашей попытки, пожалуйста –