Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Генерация произвольных идентификаторов  [new]
abc_da
Member

Откуда: СПб
Сообщений: 194
Добрый день,

Передо мной стоит задача автоматически генерировать и хранить в Oracle идентификаторы вида "ГГГГ/XXXX", где ГГГГ - номер календарного года, а XXXX - номер по порядку в рамках календарного года. С 1го января нумерация XXXX должна обнуляться. Т.е. в момент добавления новой записи в таблицу сгенерированный идентификатор должен записываться в одно из полей.

Я плохо знаком с БД в целом, так что решение этой задачи вызвало у меня немалые трудности. Сначала мне казалось, что CREATE SEQUENCE - то, что мне нужно, но вчитавшись я засомневался.

Подскажите, пожалуйста, с помощью каких средств можно реализовать описанную мной логику?
14 дек 13, 15:34    [15292708]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
abc_da, напрашивается SEQUENCE и триггер на вставку.
Где-то хранить год последней вставки, если текущий год отличается, то обнулять счетчик.
А задним или будущим числом не потребуется что-нибудь добавлять в таблицу?
Потому как в этом случае придется держать на каждый год свой счетчик.
14 дек 13, 15:55    [15292737]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10045
Alexander_Ttl
abc_da, напрашивается SEQUENCE и триггер на вставку.
Где-то хранить год последней вставки, если текущий год отличается, то обнулять счетчик.


Что означает сериализацию и все связанные с ней проблемы производительности. Насоздать последовательностей SYYYY на 100 лет вперед + триггер c динамическим SQL на выборку из соответствующей последовательности.

SY.
14 дек 13, 16:10    [15292761]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
SY,
реплика, наверное, про вторую часть "свой счетчик"?
Согласен, вариант не очень.
14 дек 13, 16:33    [15292810]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
abc_da
Member

Откуда: СПб
Сообщений: 194
Alexander_Ttl, спасибо. Выглядит не очень просто, но проще, как я понимаю, никак?

Alexander_Ttl
А задним или будущим числом не потребуется что-нибудь добавлять в таблицу?
Потому как в этом случае придется держать на каждый год свой счетчик.

в настоящий момент такое требование отсутствует.

автор
Что означает сериализацию и все связанные с ней проблемы производительности. Насоздать последовательностей SYYYY на 100 лет вперед + триггер c динамическим SQL на выборку из соответствующей последовательности.

Можете пояснить подробнее? Как я писал выше, я плохо знаком с БД.
14 дек 13, 16:39    [15292820]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
abc_da,
не знаю, насколько проще будет, можно написать свой счетчик - функцию, которая в в зависимости от года будет давать новое уникальное значение.
Если табличка небольшая, проиндексирована по этому полю, а вставка происходит не часто, можно и вообще без счетчиков обойтись, а следующее значение вычислять, например, как max+1.
14 дек 13, 16:54    [15292848]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Casey.
Guest
SY
Насоздать последовательностей SYYYY на 100 лет вперед + триггер c динамическим SQL на выборку из соответствующей последовательности.

SY.
А чем case extract year не подойдет?
14 дек 13, 16:54    [15292850]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54383
SY
Alexander_Ttl
abc_da, напрашивается SEQUENCE и триггер на вставку.
Где-то хранить год последней вставки, если текущий год отличается, то обнулять счетчик.


Что означает сериализацию и все связанные с ней проблемы производительности. Насоздать последовательностей SYYYY на 100 лет вперед + триггер c динамическим SQL на выборку из соответствующей последовательности.

SY.
создать таблицу-нумератор одну и забить ее на сто лет вперед
14 дек 13, 16:56    [15292857]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Casey.
Guest
andreymx
создать таблицу-нумератор одну и забить ее на сто лет вперед
Купить для нее отдельный винт на 1TB и создать на нем отдельный tablespace
14 дек 13, 17:16    [15292902]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
Alexander_Ttl
Если табличка небольшая, проиндексирована по этому полю, а вставка происходит не часто, можно и вообще без счетчиков обойтись, а следующее значение вычислять, например, как max+1.

Только в этом случае нужно учитывать, что две сессии одновременно могут попытаться выполнить вставку, получат один и тот же номер. От этого защитит уникальный индекс и перехват исключения DUP_VAL_ON_INDEX.
14 дек 13, 17:29    [15292926]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54383
Casey.
andreymx
создать таблицу-нумератор одну и забить ее на сто лет вперед
Купить для нее отдельный винт на 1TB и создать на нем отдельный tablespace
1ТБ на 100 тыс строк? или ты туда фильмы собрался писать?
14 дек 13, 18:22    [15293036]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10045
Casey.
А чем case extract year не подойдет?


КаК достать год из SYSDATE - неважно. Ну и как ты будешь доставать SYYYY.NEXTVAL без динамического SQL.

SY.
14 дек 13, 18:28    [15293048]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Elic
Member

Откуда:
Сообщений: 29980
SY
Что означает сериализацию и все связанные с ней проблемы производительности.
Соломон, мыслить шаблонно - вредно. 10000 в год - 30 в день - какая нафиг тут производительность нужна?!
Сойдёт даже unique + (AT) select max
14 дек 13, 18:43    [15293077]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5151
abc_da
Подскажите, пожалуйста, с помощью каких средств можно реализовать описанную мной логику?
Глобальные контексты.
14 дек 13, 18:44    [15293080]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Elic
Member

Откуда:
Сообщений: 29980
andreymx
создать таблицу-нумератор одну и забить ее на сто лет вперед
Ну забил, а дальше-то что?
14 дек 13, 18:44    [15293081]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54383
Elic
andreymx
создать таблицу-нумератор одну и забить ее на сто лет вперед
Ну забил, а дальше-то что?
и берешь оттуда ещё не занятые
это если ему без дырок
14 дек 13, 18:47    [15293086]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Elic
Member

Откуда:
Сообщений: 29980
andreymx
Elic
Ну забил, а дальше-то что?
и берешь оттуда ещё не занятые
Договаривай. Как берешь?
14 дек 13, 18:49    [15293089]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
Набросал примерно функцию-нумератор.
Если допускаются дырки.
Если дыр не должно быть, то pragma autonomous_transaction нужно убрать и commit, но тогда блокировка может повиснуть.

create table year_seq_service
(
seq_year number(4,0) primary key,
seq_num number(4,0) Not Null
)

create or replace function year_seq(p_year number) return NUMBER is
v_num year_seq_service.seq_num%TYPE ;
e_busy exception ;
pragma exception_init(e_busy,-54) ;
pragma autonomous_transaction ;
begin
select seq_num into v_num from year_seq_service where seq_year=p_year for update wait 5 ;
update year_seq_service set seq_num=seq_num+1 where seq_year=p_year ;
commit ;
return v_num+1 ;
exception
 when No_data_found then
 insert into year_seq_service values (p_year,1) ;
 return 1 ;
 when e_busy then
 Null ; -- Можно как-нибудь обработать исключение
end ;
14 дек 13, 19:14    [15293151]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
Забыл воткнуть коммит после инсерта.

create or replace function year_seq(p_year number) return NUMBER is
v_num year_seq_service.seq_num%TYPE ;
e_busy exception ;
pragma exception_init(e_busy,-54) ;
pragma autonomous_transaction ;
begin
select seq_num into v_num from year_seq_service where seq_year=p_year for update wait 5 ;
update year_seq_service set seq_num=seq_num+1 where seq_year=p_year ;
commit ;
return v_num+1 ;
exception
 when No_data_found then
 insert into year_seq_service values (p_year,1) ;
 commit ;
 return 1 ;
 when e_busy then
 Null ; -- Можно как-нибудь обработать исключение
end ;
14 дек 13, 19:24    [15293181]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Elic
Member

Откуда:
Сообщений: 29980
Alexander_Ttl
pragma exception_init(e_busy,-54) ;
... for update wait 5 ;

 when e_busy then
 Null ; -- Можно как-нибудь обработать исключение
Не нужно. Оно всё равно не возникнет. RTFM
14 дек 13, 19:31    [15293211]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
Упс! и прерывание не то перехватил:
pragma exception_init(e_busy,-30006) ;
14 дек 13, 19:33    [15293215]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Elic
Member

Откуда:
Сообщений: 29980
Alexander_Ttl
прерывание
RTFM exception
14 дек 13, 19:43    [15293261]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Alexander_Ttl
Member

Откуда: Новосибирск
Сообщений: 158
Elic, ага, исключение.
14 дек 13, 19:47    [15293275]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
Casey.
Guest
SY
КаК достать год из SYSDATE - неважно. Ну и как ты будешь доставать SYYYY.NEXTVAL без динамического SQL.

SY.
Я имел ввиду case'ом не определять имя сиквенса, а определять из какого вытаскивать, например в переменную, а ее потом в values просто всунуть.
Но видимо это все-таки будет не так компактно как с динамикой, и займет больше говнокода, пусть хотя бы на 5 лет

andreymx
1ТБ на 100 тыс строк? или ты туда фильмы собрался писать?
Я воспринял маску ХХХХ просто как маску... а не маску с заданым колвом символов. Если б я не знал сколько значений в году потребуется, то так бы и написал


Alexander_Ttl, помоему ты слишком увлекся, или даже перестарался...
14 дек 13, 20:00    [15293306]     Ответить | Цитировать Сообщить модератору
 Re: Генерация произвольных идентификаторов  [new]
abc_da
Member

Откуда: СПб
Сообщений: 194
andreymx, с дырками мне ок.

Alexander_Ttl, спасибо за помощь.

Подскажите, как мне вызвать функцию из триггера? И как в триггере получить доступ к строке, которая вставляется в БД?
14 дек 13, 21:48    [15293670]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить