Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.14;
Скачать: [xml.tar.bz2];




Вниз

Как красиво исполнить INSERT? 


Duce   (2002-02-14 12:37) [0]

Милостивые а равно и сведующие государи!

Delphi6 + Oracle7.

Есть нечто вроде ленточной формы, в которой отображаем несколько записей и
ползаем по набору данных отображая несколько записей в ленте.
При добавлении записи все панельки -формы зачищаются и в верхней юзер
вводит запись, затем жмет Save, вот и дальше надо исполнить INSERT на
табличке где ID безусловно заполняется триггером из SEQUENCE. Все ОК, но
после лента формочек-записей обновить надо и крайне желательно отобразить
вновь добавленную запись в ленте(скажем вверху) и установить на ей курсор БД.
Нужно залокалить по ID и перечитать несколько записей на ленту.все ОК.
Но вот как ID -то узнать!? Дело в том,что забой в БД идет очень интенсивно и как
показывает практика, между Query.Close и Query.Open вполне может добавиться еще
чужих записей с других мест других мест. Мне в голову ничего, кроме как лочить таблицу перед вставкой, после встаки брать MAX ID для позиционирования и отпускать таблицу не приходит(а тормоза???). Не привязывать же записи к юзерам! Что делать?



Fay   (2002-02-14 14:31) [1]

Я в Оракле не копенгаген, но думаю что и там есть хранимые процедуры с аутпут-параметрами.



Внук   (2002-02-14 15:06) [2]

Самый здесь оптимальный путь, на мой взгляд - это после Insert попытаться выполнить запрос типа
Select MySequence.CurrVal from dual;
Он вернет последний ID, причем ORACLE гарантирует, что ID будет последним для ТЕКУЩЕЙ СЕССИИ, то есть именно то, что надо.
Два требования - разные пользователи работают в разных сессиях, и разные последовательности управляют разными таблицами.
Если что непонятно - могу объяснить подробнее.



Sergey13   (2002-02-15 10:46) [3]

Я делаю это так. В тригере делаю не безусловное заполнение из последовательности, а по условию
if :new.id is null then
select MySequence.Nextval into :new.id from dual;
end if;

А в приложении, если мне надо узнать CurVal, в строку инсерта явно забиваю NextVal типа
insert into MyTable(id,name) values(MySequence.Nextval,"Бла-бла")
потом читаю
select MySequence.CurVal from dual
и гарантировано получаю этот самый ID т.к. запрос к сиквенсу осуществляется в одной сессии. А для таюблицы по барабану где заполняется IDшник, главное что из одного сиквенса.

2Внук
Я не помню, тригер выполняется под СЕССИЕЙ ПОЛЬЗОВАТЕЛЯ(он ведь выполнятся с правами владельца) или как то автономно. Надо будет проверить, самому интересно стало. Если первое то ты полностью прав. Если второе то правильнее будет мой вариант, так как запрос nextval и curval гарантировано происходят в одной сессии, что при итенсивной вставке разными юзерами очень важно.
Правда твои "требования" по моему - чепуха
1. разные пользователи и не могут ОДНОВРЕМЕННО работать в одной сессии, а при указании схемы в запросе, пользователь значения не имеет, лишь бы права были.
2. а какая разница в сколько таблиц я вставляю данные из сиквенса? А может по другому и не сделаешь. Если допустим надо чтобы ключи не пересекались для 2(3,4,5...)таблиц.



Внук   (2002-02-15 13:32) [4]

>>Sergey13 ©
Тоже вариант, только непонятно, зачем тогда здесь вообще нужен триггер. И как-то сложно это :)
Насчет сессии - действительно, проверьте. Это убедит Вас лучше, чем я. В этом смысле триггер, по-моему, не отличается от хранимых процедур, а с их использованием все работает.
Насчет требований:
1. Наверное, мы говорим о разных вещах. Я под пользователем имел в виду не пользователя ORAСLE, а пользователя программы. Пример: пишу трехзвенное приложение. Сервер приложения - COM-объект, живущий в единственном экземпляре для всех клиентов. Каждый клиент при запуске получает ссылку на одну и ту же сессию. Здесь начнется веселье со значением CurVal.
2. Иногда бывает нужно выполнить "каскадный" Insert. То есть успешно вставить в разные таблицы соответствующие записи, или при ошибке не вставлять ничего. Если для этих таблиц используется одна и та же последовательность, невозможно (или затруднительно) определить ID записи, вставленной в первую по очереди таблицу.
Эти условия я не выдумываю, а привожу исходя из собственного опыта :-)



Duce   (2002-02-15 17:15) [5]

ОГРОМНОЕ СПАСИБО ЗА КОНСАЛТ!!!
Действительно, secuence.currval хвала богам,
сохраняеть значение для сессии -самое простое и
думается быстрое решение. Вставляю я по одной записи,
без накопления, в двузвеннике... А триггер его породитель не
захотель ифить...Ну и не надА! :-))




Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.14;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.73 MB
Время: 0.015 c
4-43210           MystiX                2002-01-13 15:59  2002.03.14  
Помогите!!!


3-42952           Font Hunter           2002-02-15 13:12  2002.03.14  
Перекодировка при перекачке данных из Paradox в Interbase


3-42916           ser_ker               2002-02-14 10:51  2002.03.14  
Как заставить программу работать через ODBC без BDE ?


14-43144          Digitman              2002-01-29 18:42  2002.03.14  
О


7-43208           Alexander Beliy       2001-12-10 14:18  2002.03.14  
Вопрос про модем