C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Как обновить запись после срабатывания триггера
Nichka
Отправлено: 19.04.2005, 16:56


Не зарегистрирован







Ситуёвина такая:

1. Добавляю запись в табличку, типа
DataSet->Insert();
bla-bla;
DataSet->Post();
2. Эту запись обрабатывает в базе триггер и меняет некоторые значения полей.
3. Далее мне нужно по определнному условию эту же запись в программе изменить, типа
DataSet->Edit();
bla-bla-bla;
DataSet->Post();

Но после срабатывания триггера запись меняется,
а программа остается со старыми значениями и при следующем изменении выдает ошибку, типа "кто-то левый её (запись) уже изменил".

Вот. Хотелось бы спросить совета,
как лучше обновить запись (табличку) так, чтобы не потерять только что вставленную запись?

Пробывал ставить закладку TBookmark, но после Refresh() её она пропадает...

Причем не хочется пользоваться прямо
Refresh(); Locate(bla-bla);
поскольку постолько, что на месте описанной таблички могут быть совершенно разные реальные таблицы с разными первичными ключами, причем в большом количестве. А писать всевозможные варианты лень.

На всякий случай база Sybase, а компонеты TSaDs из состава TSaVcl.

Заранее спасибо.
olegenty
Отправлено: 20.04.2005, 08:18


Ветеран

Группа: Модератор
Сообщений: 2412



я, наверное, уже урекламировался TMemTableEh, который умеет обновлять ОДНУ запись.
xim
Отправлено: 20.04.2005, 20:22


Станционный диспетчер

Группа: Участник
Сообщений: 143



to olegenty: Уметь-то они умеют все (dataset-ы) — только через обертку над субдэшной API клиента
(пример обертки — OLEDB Provider for 'bla-bla-bla' -> ADO)

Для ADO можно было написать так:

CODE
ADODataSet#->UpdateCursorPos();
ADODataSet#->Recordset->Requery(0);
ADODataSet#->Resync(TResyncMode());


Для TSaDs может существовать подобный метод.

Можно покопать в сырцах protected метод InternalRefresh для TSaDs. В нем проходит выдергивание изменений для всего набора. Скорее всего можно что-то оттуда вытянуть.
olegenty
Отправлено: 21.04.2005, 07:08


Ветеран

Группа: Модератор
Сообщений: 2412



это понятно, но ввиду того, что он клиентский до обалдения, у него даже запрос есть на обновление одной текущей записи (точнее, у TADODataDriverEh). и метод у TMemTableEh, типа RefreshRecord() — куда уж проще. а то, что это можно везде, я не сомневаюсь. smile.gif
xim
Отправлено: 21.04.2005, 12:04


Станционный диспетчер

Группа: Участник
Сообщений: 143



TADODataDriverEh, насколько я понимаю, можно использовать только при наличии соответствующего OLEDB Provider. Вопрос в том, — можно ли сделать RefreshRecord() для SaVCL, использующей API Sybase.

(2Nichka: см. SaDB.pas метод TSaDs.DoGlBuf)

User Attached Image Скачать файл
SaDb.arj


xim
Отправлено: 21.04.2005, 12:07


Станционный диспетчер

Группа: Участник
Сообщений: 143



Все исподники SaVCL (на всяк. случай)


User Attached Image Скачать файл
savcl_cp.arj


Nichka
Отправлено: 22.04.2005, 00:32


Не зарегистрирован







Мои иследования привели к следующим результатам:

Во-первых, в описании SaVCL фишка
QUOTE
вставки записи непосредственно в курсор с одновременным
получением реально вставленных значений.
вынесена отдельным пунктом и расхвалена до невозможности.
Во-вторых, как я понял, что достаточно было поставить свойство soInsertInToCursor в положение true (что и происходит по умолчанию) и все должно происходить само-сабой. Но мне оно не помогало...
В кишках сколько не рылся ничего придумать не смог.

В итоге понял от чего у меня пропадала закладка TBookmark.
Просто выборка была с фильтрацией и эта запись не попадала в нее.
Фильтрацию убрал и всё решилось старым добрым методом из хелпа.
CODE

SavePlace = Table1->GetBookmark();
Table1->Refresh();
Table1->GotoBookmark(SavePlace);
Table1->FreeBookmark(SavePlace);

Кстати в кишках до боли похожая картинка обновления, только вот уровень более низкий.

Уф... спасибо всем за советы и потдержку.

Вернуться в Работа с базами данных в C++Builder