Страница 1 из 1

Динамический SQL

Добавлено: 04 фев 2005, 12:22
Romikk
День добрый!

Столкнулся с трудностями в следуюшей ситуации

есть форма для редактирования пары полей, использую компонент
TIBDataSet, до момента открытия DataSet'a заполняю свойства

lSql := 'select ID_MAIL,MAIL_LOGIN,MAIL_PASSWD
where ID_MAIL=:IID_MAIL';
QSelect.SQL.Clear(); QSelect.SQL.Add(lSql);

lSql := 'update MAIL set MAIL_LOGIN=:IMAIL_LOGIN,MAIL_PASSWD=:IMAIL_PASSWD
where ID_MAIL=:IID_MAIL';
QModify.SQL.Clear(); QModify.SQL.Add(lSql);

Тут клиент редактирует данные и пытается их сохранить

Перед событием Post я заполняю поля запроса
QModify.Params.ByName('IMAIL_LOGIN').asString := Trim( FieldByName('MAIL_LOGIN').asString);
QModify.Params.ByName('IMAIL_PASSWD').asString := Trim(FieldByName('MAIL_PASSWD').asString);

В чем трудность: если пользователь отредактировал только одно из двух полей, как мне удалить подавить обновление в базе второго поля
(которое не редактировалось) простая пересборка SQL выражения не подходит, тк набор данных уже открыт.

Добавлено: 04 фев 2005, 13:19
Merlin
Перелопатить сорцы IBX. Или попробовать FIBPlus, вроде бы там это уже сделали.

Добавлено: 04 фев 2005, 14:17
kdv
эта. теоретически упаковка записи приведет к тому, что размер обновлений столбца "старым" значение можно игнорировать.

Другое дело, что раньше в BDE был режим UpdateMode = upWhereAll, upWhereChanged и upWhereKeyOnly. в IBX/FIBPlus как таковой используется только upWhereKeyOnly при авто-построении SQL update.
Я про
update
set a= new_value, b= new_value
where id = :id and a = old_a and b= old_b.

то есть, гарантированное обновление изменений именно измененных столбцов, со старого значения на новое. Так сказать, ручной контроль взаимосвязи столбцов.

Добавлено: 04 фев 2005, 14:39
Merlin
kdv писал(а):эта. если мне не изменяет память, то при update если делается set a=a, то есть значения совпадают, то в новую версию этот столбец тоже не попадает. То есть теми же значениями можно смело апдейтить - это не увеличит размер записи из-за "ненужных" обновлений столбцов.
Я может осторожничаю излишне, но. А как там если поля индексированные? Не бросится ли сначала лопатить индекс, а потом скажет - ааа, это ж писать-то не надо :) И ещё с блобами и длинными чарами. Их сравнить ведь тоже время надо, чтоб включать-не включать.
kdv писал(а): Другое дело, что раньше в BDE был режим UpdateMode = upWhereAll, upWhereChanged и upWhereKeyOnly. в IBX/FIBPlus как таковой используется только upWhereKeyOnly при авто-построении SQL update.
Я про
update
set a= new_value, b= new_value
where id = :id and a = old_a and b= old_b.

то есть, гарантированное обновление изменений именно измененных столбцов, со старого значения на новое. Так сказать, ручной контроль взаимосвязи столбцов.
Я похоже со страшной силой отстал от внутренней жизни IBX ибо мой экземпляр не знает что такое авто-пострение SQL update в runtime. Более того, он выполняет Prepare всех ...SQL на TIBDataSet.Open, не следит за дальнейшей модификацией текста запросов и не даёт распрепарить их самому. Поэтому попытки изменять что либо в них на фоне открытого SelectSQL приводят к AV. Алексу пришлось изрядно попотеть вокруг этой темы чтоб получить то, на чём мы с ним работаем. С явным управлением транзакцией и перепарацией каждого ...SQL, думаю примерно как в FIBPlus.

Добавлено: 04 фев 2005, 16:21
kdv
под "использованием" я имел в виду отсутствие автоматических механизмов UpdateMode, и жесткий эквивалент upWhereKeyOnly в BDE..