powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Insert FOR UPDATE
30 сообщений из 30, показаны все 2 страниц
Insert FOR UPDATE
    #39320736
Всем привет!
Есть таблица test (id number,value varchar2). Id присваиваются при инсерте триггером и сиквенсом.

Хотел написать процедуру которая добавляет еще одну строчку к таблице:

begin
insert into test05 (value) (select max(id)||'a' from test05);
end;

Но хочется чтобы это происходило с применением "последовательности сессий", т.е. с применением FOR UPDATE.
Написал это:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare 
    cursor C is
    select t.id,t.value
      from test05 t
     FOR UPDATE OF t.id; 
begin
  FOR rec in C loop
   insert into test05 (value) (select max(rec.id)||'a' from test05);
  end loop; 
  commit;  
end;


Однако оно делает этот инсерт ровно столько раз, сколько в данный момент строчек в таблице.
Вообще у меня очень плохое понимание что есть курсор, в данном случае для меня это просто "снимок" таблицы на определенный момент времени.

Прошу помочь разобраться,
Большое спасибо
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320740
Не понятно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
неоченьумен,

Может все-таки сначала цель скажешь? Чего добиться-то хочешь в итоге?
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320742
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменВообще у меня очень плохое понимание что есть курсор...
Прошу помочь разобраться
У вас очень плохое понимание, что тfкое цикл (неважно, что по курсору) - попробуйте начать с этого - что такое цикл и почему "оно делает этот инсерт ровно столько раз, сколько в данный момент строчек в таблице."
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320743
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменНо хочется чтобы это происходило с применением "последовательности сессий", т.е. с применением FOR UPDATE.
Расшифруйте пожалуйста, что вы хотели этим сказать?
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320745
Не понятно,
хочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320747
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
..а. .. понял сбило с толка вырфжение "последовательности сессий" , которое относится, как первоначално показалось, не к сессиям, а, на самом деле, к последовательности..
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320748
Не понятно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
неоченьуменНе понятно,
хочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id.
Нужно именно ЖДАТЬ? или просто нужно разные value для разных строчек? Типа еще один уникальный ключ в дополнение к id?
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320749
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хм.. неправильно понял..
А чем вам сиквенс не угодил, зачем вам велосипед?
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320754
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
неоченьумен,

lock table test05 in exclusive mode
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320756
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменхочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id .
Не понятноМожет все-таки сначала цель скажешь? Чего добиться-то хочешь в итоге?
К чему, для чего эта совершенно непонятная сторока??
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320759
Возможно я привел плохой пример, я читал книгу по ораклу и там был очень подходящий пример:

Допустим есть таблица в которой каждая строка это бронь на то или иное место в кинозале. Т.е. там будут приблизительно такие поля:
ID,Время сеанса, место, ФИО человека.

И есть приложение работающее с этой таблицей, которое перед инсертом просматривает таблицу на предмет не занято ли это время-место. Так вот если оно будет смотреть на эту таблицу без FOR UPDATE , то может получиться что два человека забронируют одно место одновременно.

Я просто хотел повторить этот процесс, написать процедуру с использованием for update и запустить ее одновременно из двух разных сессий
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320762
Не понятно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
неоченьумен,
тогда просто уникальный индекс добавь на поле value.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320768
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменВозможно я привел плохой пример, я читал книгу по ораклу и там был очень подходящий пример:
Вот возьмите тот пример в оригинале и воспроизведите дословно, без отсебятины.
Потом разберите до последнего "end;"
Попробуйте позвать из нескольких сессий и т.п.
И когда поймете что это и как именно работает - начинайте эксперименты с изменением текстов.
Открытий на Вашем пути еще очень много.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320771
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если уж вы хотите повторить, создать собственный test case, так вкладываете в него хоть какую-то логику событий. Логика событий и диктует логику реализации..
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320773
andrey_anonymous,
да в том и дело, что пример не был дословно описан было лишь упоминание что проблема решилась использованием for update
книга -Oracle для профессионалов. Архитектура, методики программирования и особенности версий
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320775
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменкнига -Oracle для профессионалов. Архитектура, методики программирования и особенности версий
Ну понятно.
Тома нашего Кайта надо читать ПОСЛЕ официальной доки, а не до.
Том реально предполагает, что его читатель уже "в теме".
Минимум, который надо освоить перед чтением Кайта или, упаси Бог, Льюиса и прочих Арупов Нандов, Кэрри Миллсапов или кого еще там найдете в магазине:
Application Development Guide на Вашу версию сервера + database concepts, как минимум - главы "Data concurrency and consistency"
Ну про SQL Reference вообще молчу.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320777
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменпример не был дословно описан
Словами пример описан самодостаточно. Ну так и пробуйте... пишите код именно в той логике событий..
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320846
Viewer,
Код: plsql
1.
2.
3.
4.
5.
  CREATE TABLE ""BRON" 
   (	"MESTO" NUMBER, 
	"SEANS_DATE" DATE, 
	"FIO" VARCHAR2(20 BYTE)
   );



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create or replace PROCEDURE FOR_BRON (MESTO# NUMBER,SEANS_DATE# DATE,FIO# VARCHAR2)
IS
CNT NUMBER;
BEGIN
SELECT v INTO CNT FROM (SELECT COUNT(*) v FROM BRON WHERE MESTO=MESTO# AND SEANS_DATE=SEANS_DATE# );
IF CNT=0 THEN
INSERT INTO BRON VALUES (MESTO#,SEANS_DATE#,FIO#);
ELSE  Raise_application_error( -20001, 'Такая запись уже есть');
END IF;
COMMIT;
END;



Я сделал вот такую процедуру, она работает. Но я все равно не понимаю в каком месте надо прикручивать FOR UPDATE чтобы реализиовать то, о чем я писал. Проблема еще и в том что не удается "словить" момент когда при одновременном нажатии в таблицу попадут две строки с одинаковым mesto,seans_date и разными FIO
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320963
Фотография Viewer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменв каком месте надо прикручивать FOR UPDATE
Как звучит в переводе фраза "select for update "?
Где здесь insert ?
Для выполнения " for update " строка должна уже существовать.
По сути "матрица" мест кинозала в таблице уже расписана (зал ведь не резиновый, не сдувается и не раздувается, не так ли?)
Другое дело, что существующее место забронировано или нет.
Попробуйте подумать в этом направлении.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39320972
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменЯ сделал вот такую процедуру, она работает.
Не работает.
Чтобы она работала - на таблице bron необходим primary или unique key по полям (MESTO,SEANS_DATE)
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321015
andrey_anonymous,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create or replace PROCEDURE FOR_BRON (MESTO# NUMBER,MESTO_DATE# DATE,FIO# VARCHAR2)
IS
CNT NUMBER;
BEGIN
FOR V IN (SELECT COUNT(1) OVER (ORDER BY 1) CNT FROM BRON S WHERE MESTO=MESTO# AND SEANS_DATE=MESTO_DATE# FOR UPDATE) LOOP
       CNT := V.CNT;
      EXIT;
    END LOOP;
    
IF CNT=0 THEN
INSERT INTO BRON VALUES (MESTO#,MESTO_DATE#,FIO#);
ELSE  Raise_application_error( -20001, 'УЖЕ ЕСТЬ ТАКАЯ ЗАПИСЬ, СЛЫШ');
END IF;
COMMIT;
END;



Эхх, вроде бы так должно работать, только не знаю как в этом удостовериться.
По поводу unique key, если сделать такой ключ, то как я понимаю при попытке внести неправильную строку оракл выдаст что-то вроде "нарушено ограничение целостности" . Просто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяля
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321020
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменПросто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяляГарантию может дать только уникальный ключ. Всё твои потуги - наивны.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321030
Elic,
Окей, я понял что самый надежный способ- уникальный ключ.
Но все-таки интересно, в чем проблема этой процедуры, почему она не обеспечивает того же самого?
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321035
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменПросто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяля
Удостовериться:
в двух сессиях параллельно запустить
begin
FOR_BRON (7654, trunc(sysdate),'Вася Пупкин');
end;
затем, когда отработает - закоммитить обе сессии.
Убедиться, что данные задублированы.

Чтобы процедура "просто не позволяла" - то нужно наложить ограничение уникальности и обрабатывать exception в процедуре.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321074
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И это, в каком кинотеатре не стоит покупать билеты онлайн? :)
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321084
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неоченьуменandrey_anonymous,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create or replace PROCEDURE FOR_BRON (MESTO# NUMBER,MESTO_DATE# DATE,FIO# VARCHAR2)
IS
CNT NUMBER;
BEGIN
FOR V IN (SELECT COUNT(1) OVER (ORDER BY 1) CNT FROM BRON S WHERE MESTO=MESTO# AND SEANS_DATE=MESTO_DATE# FOR UPDATE) LOOP
       CNT := V.CNT;
      EXIT;
    END LOOP;
    
IF CNT=0 THEN
INSERT INTO BRON VALUES (MESTO#,MESTO_DATE#,FIO#);
ELSE  Raise_application_error( -20001, 'УЖЕ ЕСТЬ ТАКАЯ ЗАПИСЬ, СЛЫШ');
END IF;
COMMIT;
END;



Эхх, вроде бы так должно работать, только не знаю как в этом удостовериться.
По поводу unique key, если сделать такой ключ, то как я понимаю при попытке внести неправильную строку оракл выдаст что-то вроде "нарушено ограничение целостности" . Просто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяля

for update заблокирует СУЩЕСТВУЮЩУЮ запись, у Вас ее нет, она еще не вставлена
поетому для етой задачи for update не подходит
вернее подходит но с усложненнием, напр есть схема мест кинозала

берем Ваш первый вариант (без over)
шоб тестировать добавте после INSERT INTO BRON VALUES (MESTO#,SEANS_DATE#,FIO#);
dbms_lock.sleep(20) ждать 20 секунд
и запустите в двух сессиях на протяжении 20с
увидете результат


зы
прислушайтеcть к Елику насчет уник. индекса

.......
stax
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321093
Не понятно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,
Про уникальный индекс раньше было 19744862 :)
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321099
j2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понятноstax..,
Про уникальный индекс раньше было 19744862 :)
если бы ваш ответ приняли дословно, то места бы были только на утренние сеансы и всего один раз :D
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321101
Не понятно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
j2k, на тот момент в словаре было только id и value. остальные колонки появились позже.
...
Рейтинг: 0 / 0
Insert FOR UPDATE
    #39321398
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понятноstax..,
Про уникальный индекс раньше было 19744862 :)
тут вопрос даж не в етом
разные СУБД по разному пашут
про оракля, ето важно, грубо говоря запретить чтение нельзя
for update если грубо то ето update ф=ф
такая философия
я не сразу к етому пришел
заблокировть чтение в оракле большая проблема
я на счет max(xxx)

.....
stax
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Insert FOR UPDATE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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