|
ADO + триггеры-обманщики
|
|||
---|---|---|---|
#18+
Я в Delphi ковыряюсь недавно. До этого все больше на Access, поэтому сильно не пинайте, а лучше подробнее разъясните . Сделал цепочку ADOQuery - DataSource - DBGrid для работы с View, через который видны только нужные поля нужных записей таблицы. Таблица со встроенной журнализацией. Журнализацией занимаются триггеры. При добавлении в таблицу записи автоматически фиксируется, какой юзер это сделал, когда, с какого компьютера, на каком удаленном сервере (между серверами работает репликация). При попытке изменения записи триггер перехватывает ее, восстанавливает прежнее содержимое изменяемой записи, одновременно помечая ее как логически удаленную, и тут же создает новую запись с фиксацией всех указанных выше атрибутов уже для новой редакции записи - то есть в таблице остается прежняя редакция записи, помеченная как логически удаленная и одновременно с ней новая редакция той же записи. При попытке удаления запись тоже удаляется не физически, а логически с фиксацией всей атрибутики ее "киллера". Таким образом, в таблице находятся как действующие на данный момент записи, так и истории модификации записей (журнал). Записи этой таблицы имеют два идентификатора. Один идентификатор, уникальный для каждой РЕДАКЦИИ (RowGUID - используется для репликации), а второй уникальный для каждой совокупности редакций - для всех редакций одной и той же записи он одинаковый. Через VIEW видны только последние редакции записей, причем только тех, которые НЕ удалены логически - то есть так, как будто никакой истории записей не ведется. Содержимое этого View просвечивает в DBGrid, из которого я и пытаюсь работать с источником данных. Теперь, собственно, проблема. Она заключается в том, что мои триггеры "обманывают" клиентский курсор. Когда пользователь отредактировал запись, в клиентском курсоре запоминается измененное содержимое этой записи так как если бы она на самом деле изменилась в таблице. Проблема же заключается в том, что запись, буферизованная в курсоре, на самом деле в таблице не изменилась, а в View вместо нее появилась СОВЕРШЕННО другая запись (с другим кодом ROWGUID). Из-за того, что на клиентское приложение запутывается, какие записи какими являются, прут ошибки. К примеру, при первой модификации поля Name (видимого в DBGrid), в нем аккуратно оно изменяется, но в скрытом поле идентификатора записи значение после этой операции оказывается некорректным (идентификатор изменяется триггером, а в DBGrid остался без изменения). Если после этого попытаться еще раз произвести модификацию поля Name в этой же записи, выскочит ошибка, что запись куда-то исчезла. Метод Requery приводит DBGrid в чувство, но мне этот вариант не нравится. Если после каждого шевеления данными повторно считывать весь массив данных в локальный курсор, все преимущества клиент-серверной технологии перед файл-серверной летят прахом. Вопрос 1. Можно ли синхронизировать данные на сервере и клиенте менее ресурсоемким способом? Я слышал, что как-то это можно делать с помощью Resync. Покопался, но у меня ничего не вышло. Вопрос 2. Как можно БЫСТРО установить курсор на только что модифицированную запись после выдачи Requery (по идентификатору группы редакций, который у прежней и новой редакции записи одинаковый)? Locate работает медленно. В методах ADOQuery маячит Seek, но как им пользоваться в этом компоненте, толком не пойму. В книжке Астраханского написано, что свойство IndexName хотя и присутствует в инспекторе объектов для ADO-компонентов, на самом деле не используется. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.12.2000, 20:47 |
|
ADO + триггеры-обманщики
|
|||
---|---|---|---|
#18+
Когда запись модифицируется триггером, то эта модификация производится в отдельной от клиента сессии. Так что никакого обмана нет. Просто запоминай значение ключа модифицированной записи, и возвращайся к нему, используя Locate. А чтоб работало быстрее, давай клиенту редактируемый набор данных в виде временной таблицы. У меня под Sybase работает пулей на сотнях тысяч записей. thunder@smit.kharkov.ua ... |
|||
:
Нравится:
Не нравится:
|
|||
13.02.2001, 17:45 |
|
|
start [/forum/topic.php?fid=58&fpage=2092&tid=2120222]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
40ms |
get tp. blocked users: |
2ms |
others: | 257ms |
total: | 365ms |
0 / 0 |