powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / sequence без пропусков
32 сообщений из 32, показаны все 2 страниц
sequence без пропусков
    #40017212
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток. Имеется Oracle 11.2.0.3 Enterprise Edition.
Задача, использовать последовательность sequence в качестве уникального ключа без пропусков в нумерации.
Вопрос в той или иной степени много раз поднимался (судя по поиску на форуме), но нормальной реализации
я так и не смог найти.

Задача, при insert строки в таблицу test1, при условии что значение поля kl > 5, после commit происходит insert
в таблицу test2, в которую передается значение поля id из таблицы test1. При этом значение поле id в таблице test2
это последовательность, без пропусков, начинается с 1, в конце года обнуляется и с первого января вновь начинается с 1.
Данные в таблицу test2 попадают только через триггер на таблице test1.

В клиент-серверном приложении, откуда пользователи вносят данные, доступа нет, могу ограничения накладывать только через
Oracle. Пользователь иногда вносит данные в таблицу test1, но потом либо связь пропадает, либо он передумывает и кнопку отправить не нажимает,
не знаю что происходит, никак отловить его не могу, но последовательность нарушается в test2 и появляются пропуски, а это очень критично.
В год в таблицу test2 попадает не более 2500 записей.
Подскажите в какую сторону копать?


--Создаем таблицы
create table test1(id number(8), str varchar2(16), kl number(8));
/
create table test2(id number(8), str varchar2(16));
/
--Создаем последовательности
create sequence seq_test1
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
nocache;
/

create sequence seq_test2
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
nocache;
/
--Создаем триггеры

create or replace trigger TR_INS_test1
for insert ON test1
compound trigger
tId number(16) :=0;
tKl number(16) :=0;

before statement is
begin
null;
end before statement;

before EACH ROW IS
BEGIN
:New.id := seq_test1.nextval;
END before EACH ROW;

after each row is
begin
tId := :New.id;
tKl := :new.kl;
if (tkl > 5) then
insert into test2(str) values (tId);
end if;
end after each row;

after statement is
begin
null;
end after statement;

end TR_INS_test1;
/
create or replace trigger TR_INS_test2
before INSERT ON test2
FOR EACH ROW
DECLARE
BEGIN
:New.id := seq_test2.nextval;
end TR_INS_test2;

/
--Запросы

insert into test1(str,kl) values ('Test1','7');
commit;
insert into test1(str,kl) values ('Test2','8');
rollback;
insert into test1(str,kl) values ('Test3','1');
commit;
insert into test1(str,kl) values ('Test4','4');
rollback;
insert into test1(str,kl) values ('Test5','8');
commit;
/
--Выводим результат
select * from test1;
select * from test2;

В выборке из test2 2 записи, но поле id должно иметь значения 1 и 2. А не 1 и 3.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017216
dmdmdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача, использовать последовательность sequence в качестве уникального ключа без пропусков в нумерации .

На мой взгляд, задача с помощью секвенсов не решается, они придуманы не для этого.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017219
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,

Конечно, нахрена?
Но если очень хочется, то последовательный доступ на вставку, сиквенс реализовать путем записи в отдельной таблице currvalue.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017220
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
--Создаем последовательности
create sequence seq_test1
Напрасно.
estro
Вопрос в той или иной степени много раз поднимался (судя по поиску на форуме), но нормальной реализации
я так и не смог найти.
1132766
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017224
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dmdmdm,

ваши предложения?
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017229
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic,

max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать? Сессии пользователей я не контролирую. И задачу они выполняют не одну.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017231
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro

В выборке из test2 2 записи, но поле id должно иметь значения 1 и 2. А не 1 и 3.


у Вас есть rollback
Код: plsql
1.
2.
insert into test1(str,kl) values ('Test2','8');
rollback;



rollback не откатывает последовательности
Вы двойку спалили при инсерте ('Test2','8');

после каждого инсерт (до commit/rollback) поставте вывод с тест2(сразу станет ясно)

чтоб не было дырок из за роллбека надо менять алгоритм выдачи ид

....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017234
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать?
Чем навеян этот бред?
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017235
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

Спасибо, но я не потерял двойку, я просто имитировал ситуацию, показывая когда образуются дырки в последовательности. На что поменять, последовательность удобна, раз в год ее обнуляешь и все по новой. Вариант с таблицей вместо последовательности тоже устроит, но как реализовать чтобы не было дырок и дублей?
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017237
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic
estro
max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать?
Чем навеян этот бред?


Прочитал ветку, на которую дали ссылку.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017240
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
Прочитал ветку, на которую дали ссылку.
С косоглазием не помогу.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017256
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic
estro
Прочитал ветку, на которую дали ссылку.
С косоглазием не помогу.

Если бы были проблемы со здоровьем, обратился бы к доктору, а не на форум sql.ru.

В выделенном вами выше сообщении на ваш ответ в другой ветке не вижу ответа по теме.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017259
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estromax(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

Не могут. Ограничение уникальности не даст.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017261
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,
estro
В выделенном вами выше сообщении на ваш ответ в другой ветке не вижу ответа по теме.

А если почитать сообщения выше?
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017263
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
Elic,

max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать? Сессии пользователей я не контролирую. И задачу они выполняют не одну.

Елик не то (не max(id) + 1) советовал

заводите табличку my_seq_test2(current_val number);
insert into my_seq_test2 values(0); -стартовое значение
в триггере TR_INS_test2
update my_seq_test2 set current_val=current_val+1 ...RETURNING current_val INTO v_currval;

:New.id :=v_currval;

если паралельно работает много инсертов выстроится очередь (почти однопользовательский режим)

зы
имхо, без блокировок дырки неизбежны
зыы
дырку "хранить" и выдавать повторно

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017266
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env
estro,
estro
В выделенном вами выше сообщении на ваш ответ в другой ветке не вижу ответа по теме.

А если почитать сообщения выше?


Вы извините, но все равно решения не увидел.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017269
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
estro
Elic,

max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать? Сессии пользователей я не контролирую. И задачу они выполняют не одну.

Елик не то (не max(id) + 1) советовал

заводите табличку my_seq_test2(current_val number);
insert into my_seq_test2 values(0); -стартовое значение
в триггере TR_INS_test2
update my_seq_test2 set current_val=current_val+1 ...RETURNING current_val INTO v_currval;

:New.id :=v_currval;

если паралельно работает много инсертов выстроится очередь (почти однопользовательский режим)

зы
имхо, без блокировок дырки неизбежны
зыы
дырку "хранить" и выдавать повторно

.....
stax


Большое спасибо. Все работает как нужно.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017273
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
estro
Elic,

max(id) + 1 крайний вариант, и даже если 10 записей в день вставят, то могут быть совпадения.

alter session set isolation_level = serializable куда мне прописать? Сессии пользователей я не контролирую. И задачу они выполняют не одну.

Елик не то (не max(id) + 1) советовал

заводите табличку my_seq_test2(current_val number);
insert into my_seq_test2 values(0); -стартовое значение
в триггере TR_INS_test2
update my_seq_test2 set current_val=current_val+1 ...RETURNING current_val INTO v_currval;

:New.id :=v_currval;

если паралельно работает много инсертов выстроится очередь (почти однопользовательский режим)

зы
имхо, без блокировок дырки неизбежны
зыы
дырку "хранить" и выдавать повторно

.....
stax


А как можно хранить дырку? Вообще решение заменить последовательность таблицей с одной строкой полностью устраивает, ее можно и обнулять раз в год, как мне и нужно. Но получается можно использовать и последовательность в моей задаче, с хранением и повторной выдачей дырок. Как это сделать? Для удовлетворения интереса просто.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017282
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro

Для удовлетворения интереса просто.

Напр
1) завести 10000 строк и отмечать флажком спаленные
2) искать дырки в тест2 и выдавать (на время поиска дырки/мах+1 блокировать ресурс)

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017300
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем тему можно закрывать, сделал таблицу-последовательность по годам, надеюсь теперь забуду об этой задаче, но не забуду метод.

create table my_seq_test2(current_valnumber(8),yyyy number(4));
/
create or replace trigger TR_INS_test2
before INSERT ON test2
FOR EACH ROW

DECLARE
v_curval number(8) := 0;
xc integer := 0;
xYear number(4) := to_number(to_char(sysdate, 'yyyy'));
BEGIN
select count(1) into xC from my_seq_test2 where YYYY = xYear;
if (xC > 0) then
update my_seq_test2
set current_val = current_val + 1
where YYYY = xYear
returning current_val into v_curval;
else
insert into my_seq_test2 (current_val, YYYY) values (0, xYear);

update my_seq_test2
set current_val = current_val + 1
where YYYY = xYear
returning current_val into v_curval;
end if;
-- :New.id := seq_test2.currval;
:New.id := v_curval;
end TR_INS_test2;

Понял о чем говорили добрые и злые люди, давая ссылку на другую тему :). Всем спасибо, всем добра. Надеюсь информация будет кому-то еще полезна.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017313
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,

в триггере проверять год, лишняя нагрузка, да и есть манюхинькая вероятность дублирования лет

я добавил наперед лет так 10/25 и проверку с трригера убрал

зы
если проверять, то можно после update

if sql%rowcount=0 then --<> 1
....

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017596
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
В общем тему можно закрывать, сделал таблицу-последовательность по годам, надеюсь теперь забуду об этой задаче, но не забуду метод.


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE TABLE SEQ_TBL(
                     N NUMBER
                    )
/
ALTER TABLE SEQ_TBL
  ADD CONSTRAINT PK_SEQ_TBL
    PRIMARY KEY(
                N
               )
/
INSERT
  INTO SEQ_TBL
  VALUES(
         0
        )
/
CREATE OR REPLACE
  FUNCTION GET_NEXTVAL
    RETURN NUMBER
    IS
        PRAGMA AUTONOMOUS_TRANSACTION;
        V_N NUMBER;
    BEGIN
        UPDATE SEQ_TBL
           SET N = N + 1
           RETURNING N
           INTO V_N;
        COMMIT;
        RETURN V_N;
END;
/



SY.
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017600
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

PRAGMA AUTONOMOUS_TRANSACTION;

ему надо чтоб rollback откатывал и номер

....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017635
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
SY,

PRAGMA AUTONOMOUS_TRANSACTION;

ему надо чтоб rollback откатывал и номер

....
stax

В исходном посте сказано - "без пропусков".
Это значит - без дырок
как только "rollback откатывал и номер", значит либо
a) rollback потенциально образовал дырку (а если дырка допустима, значит допустимо нарушение связи такой последовательности со временем)
либо
b) вставка идет строго последовательно, в однопользовательском, по существу, режиме, либо с глобальной блокировкой.
Такие конструкции не то, чтобы совсем не летают, но очень очень нызенько,
и,в целом, неважнецки.

Их и технчески нельзя заствить выше какого-то не очень высокого потолка,
и логически люди относятся к теме как к "просто последовательности", совсем нередко принимая решения, с которыми на практике
жить где-то между нельзя совсем и очень тяжело.
И особенно, если commit/rollback отложен по отношению к моменту получению значения такого "сиквенса".
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017639
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyТакие конструкции не то, чтобы совсем не летают, но очень очень нызенько,

Такие конструкции не используются там, где люди способны оформить тысячу накладных (или
прочих документов строгой отчётности) в секунду.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017644
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

к сожалению люди - такие выдумщики....

Нет так уж редко впадаешь в глубокое изумление от детально сплетенных невиданных цветов человеческой фантазии.
И на вопрос - "А почему вот на этой стене так нарисовано?", ответ по Высоцкому - "Мы всегда на этой стене именно так рисовали..."
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017663
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby

В исходном посте сказано - "без пропусков".
Это значит - без дырок


estro привел пример почему(причину) дырки
insert into test1(str,kl) values ('Test2','8');
rollback;

конечно будет очередь, и надо просто быстро выдавать номер (максимально близко к commit)

у меня был случай (набивка банковских платежек) когда операционисты попросили замедлить вставку
опытным путем просто добавил задержку 0.6с

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017666
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
и надо просто быстро выдавать номер (максимально близко к commit)

...и еще раз скажу: задача генерации номеров документов строгой отчетности при вставке записи суть плохо поставлена и решать ее именно в такой постановке не следует .
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017677
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Stax
и надо просто быстро выдавать номер (максимально близко к commit)

...и еще раз скажу: задача генерации номеров документов строгой отчетности при вставке записи суть плохо поставлена и решать ее именно в такой постановке не следует .

я не против, на то они и строгой отчетности

просто так взять порвать и выбросить/сжечь нежелательно

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017679
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
я не против, на то они и строгой отчетности
просто так взять порвать и выбросить/сжечь нежелательно

В таком случае зачем в N-ный... не, N - мало, в M-ндатый раз толочь в ступе бессмысленную тему генерации номера без пропусков при вставке?
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017815
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous

В таком случае зачем в N-ный... не, N - мало, в M-ндатый раз толочь в ступе бессмысленную тему генерации номера без пропусков при вставке?


Вопрос был в несколько другой проскости
использование sequence и rollback приводит к дырке

замена на update задачу/проблему estro решила (насколько полно ему решать, мож у него 100 инсертов в день)

форум существует давно и практически каждую "бессмысленную тему" уже обсосали, надо токо найти

я даж сначала подумал что Неофита создали специально для поднятия активности, но ошибся

.....
stax
...
Рейтинг: 0 / 0
sequence без пропусков
    #40017825
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro
В год в таблицу test2 попадает не более 2500 записей.
Stax
замена на update задачу/проблему estro решила (насколько полно ему решать, мож у него 100 инсертов в день)
Как видишь, твоя оценка завышена.
Stax
я даж сначала подумал что Неофита создали специально для поднятия активности, но ошибся
В каждой ошибке есть доля ... ошибки.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / sequence без пропусков
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]