Работа с последовательностями

Mols

Новичок
Работа с последовательностями

Добрый день.
Вопрос такой. Есть у организации несколько филиалов. Нужно сделать журнал входящей/исходящей корреспонденции. Хотелось бы сделать нумерацию уникальную для каждого филиала. На MySQL я бы просто сделал составной первичный ключ (id_unit, id_num) - и поставил бы автоинкремент на id_num.
Как подобное сделать в ПГ ?

Можно конечно написать функцию, которая будет возвращать для каждого филиала max(id_num)+1, но тогда возникает вопрос о возможных коллизиях(возможна ли проблема если два оператора одновременно внесут изменения?). Да и агрегатные функции вроде не есть гуд.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Mols
Вопрос такой. Есть у организации несколько филиалов. Нужно сделать журнал входящей/исходящей корреспонденции. Хотелось бы сделать нумерацию уникальную для каждого филиала. На MySQL я бы просто сделал составной первичный ключ (id_unit, id_num) - и поставил бы автоинкремент на id_num.
Как подобное сделать в ПГ ?
Точно так же:
Код:
create sequence foo_seq;

create table foo (
   id_unit integer not null,
   id_num integer not null default nextval('foo_seq'),
   ...
   constraint foo_pkey primary key (id_unit, id_num)
);
 

Mols

Новичок
Я наверное не понятно выразился. Мне нужно, чтобы номера были непрерывными и уникальными для каждого филиала. То есть для каждого id_unit должно быть id_num 1,2,3,4,5.... (именно так работает описанная мной конструкция в MySQL)

-~{}~ 26.02.08 18:25:

Ну конечно насколько вообще можно применять слово "непрерывный" для целых чисел естессно ))
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Mols
Я наверное не понятно выразился. Мне нужно, чтобы номера были непрерывными и уникальными для каждого филиала. То есть для каждого id_unit должно быть id_num 1,2,3,4,5.... (именно так работает описанная мной конструкция в MySQL)
Ну "непрерывными" они не будут, т.к. выбранные из последовательности значения в случае отката транзакции повторно не используются.
А так --- пишем триггер на before insert, в триггере пытаемся выбрать nextval('foo_' . $id_unit . '_seq'), если выбрасывается исключение о несуществующей последовательности, то создаём последовательность 'foo_' . $id_unit . '_seq'.
 

Mols

Новичок
Было у меня подозрение, что придется делать последовательность для каждого филиала...
Может все таки тогда правильнее сделать функцию, которая будет возвращать следующий свободный номер?
И я вроде видел, что можно отлавливать исключения в функциях и если произошла коллизия - просто выполнить вставку повторно, вновь "спросив" следующий свободный номер?
З.Ы.
Тело функции выполняется как транзакция, я правильно понимаю?
 

MiksIr

miksir@home:~$
тогда уж лочить таблицу, делать max и потом инсерт
но с последовательностями все ж идея мне больше нравится...
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Mols
Было у меня подозрение, что придется делать последовательность для каждого филиала...
Может все таки тогда правильнее сделать функцию, которая будет возвращать следующий свободный номер?
Через выборку из таблицы по max()? Можно, кнэшно, но богатый жизненный опыт подсказывает, что вариант с последовательностями будет быстрее. Хотя, если филиалов много и не хочется плодить последовательности...

И я вроде видел, что можно отлавливать исключения в функциях и если произошла коллизия - просто выполнить вставку повторно, вновь "спросив" следующий свободный номер?
Да, можно.

Тело функции выполняется как транзакция, я правильно понимаю?
Точнее будет так: тело функции выполняется в рамках транзакции, которая её вызвала.
 
Сверху