Текущий архив: 2005.11.06;
Скачать: CL | DM;
ВнизЗнатоки ADO, покритикуйте код Найти похожие ветки
← →
Ega23 © (2005-09-23 09:43) [0]Шеф функцию написал. Не всегда корректно работает. Есть подозрение, что из-за букмарков.
Функция либо открывает запрос (sql или статический, или можно подать в качестве параметра), либо должна refresh делать.
//---- Полнофункциональное Открытие ADO-запроса (OPEN)
Function QuOpen(Qu: TDataSet;sql:string="*";refr:boolean=true;mess:string="*"):integer;
// Открытие запроса с возможностями
// - замены текста(sql),
// - рефреша с восстанавлением текущей позиции
// - вывода сообщения об ошибке
// Параметры
//sql: "*" (default) - не менять текст запроса
//refr: true (default) производить рефреш данных
//mess : "*" (default) - standart mess;
// "" - no mess
// "..some mess" - custom message
//result: Ok -RecordCount; can"t open -1;
var realsqltext:string;
BookMk: TBookmark;
begin
result:=-1;
if GpNoConnectGlb then exit;
BookMk:=nil;
Try
try
qu.DisableControls;
//заложить закладку и закрыть
if Qu.Active then
begin
BookMk := Qu.GetBookmark;
Qu.Close;
end;
//текст запроса
if sql<>"*" then (Qu as TADOQuery).sql.text:=sql;
realsqltext:=sql;
//Уже Открыть !
Qu.open;
except on E:exception do
Begin
if mess="*" then ShowMessage("Ошибка запроса")
else if mess<>"" then ShowMessage(Mess);
raise EGPException.Create(e.message+" "+mess+ " "+realsqltext);
End;
end;//try
// ЕСли просят рефреша - вот он
if refr then
try
if Qu.Active and (BookMk <> nil) and not (qu.Bof and qu.Eof) and
qu.BookmarkValid(BookMk)
then qu.GotoBookmark(BookMk);
except
end;
result:=Qu.recordcount;
if result< 0 then exit;
Finally
qu.EnableControls;
if BookMk <> nil then qu.FreeBookmark(BookMk);
End; //try fin
end;
← →
Nikolay M. © (2005-09-23 09:54) [1]Ну и бредятина, имхо. Да еще так написано... Воспринимается тяжко.
Почти наверняка из-за букмарков. Где гарантия, что после рефреша старый букмарк будет указывать на область памяти с теми же данными, что и до переоткрытия? Валидной-то закладка, может, и будет, но вот насколько корректной - вопрос.
← →
ЮЮ © (2005-09-23 09:55) [2]BookMk := Qu.GetBookmark;
Qu.Close;
после закрытия НД, букмарки следует считать "битыми", ИМХО
← →
Ega23 © (2005-09-23 10:29) [3]
> Почти наверняка из-за букмарков. Где гарантия, что после
> рефреша старый букмарк будет указывать на область памяти
> с теми же данными, что и до переоткрытия? Валидной-то закладка,
> может, и будет, но вот насколько корректной - вопрос.
Я, в общем-то, также думаю.
← →
msguns © (2005-09-23 10:51) [4]1. if GpNoConnectGlb then exit;
Что за динозавр ? Нельзя к коннекту подобраться через датасет ?
2. Закрытие НД перед анализом вх.параметров. А если просто перечитать без изменения сиквеля, когда достаточно просто выполнить ReQuery ?
имхо, некорректно
3. Совершенно некорректная работа с скл-текстом. просто q.Sql.Text := sql
приведет к тому, что сбросятся нафиг все параметры, если он были
4. Букмарки, букмарки, букмарки..
Уж сколько раз твердили миру...
Букмарки действительны ТОЛЬКО НА ТЕКУЩЕМ ДАТАСЕТЕ и теряются при его переоткрытии. Тем более, если еще и может поменяться сам запрос !
ИМХО, код будет работать только в исключительно редких случаях: непараметрический запрос, изменение запроса не приведет к изменению извлекаемого датасета, сам датасет при переоткрытии не изменится.
Отсюда вопрос: а нафиг тогда нужна такая фича ?
← →
Desdechado © (2005-09-23 10:53) [5]Ega23 ©
ARAIR, где-то с месяц назад ты сам вопрос по букмаркам задавал
и тебе объясняли, что закрытие датасета ведет к потере смысла букмарка в нем
← →
msguns © (2005-09-23 11:02) [6]Вдогонку к [4]
Знатоком ADO себя не считаю.
Шефу рекомендую заняться прямыми обязанностями (ну там на плянерки ходить, табель вести, ругаться с начальствам, ругать подчиненных и т.д.)
Еще.
Из опыта могу сказать, что модификация запроса и его переоткрытие с перепозиционированием должны быть разнесены разные блоки кода (процедуры). Если, конечно, преследуется цель унификации алгоритмики.
Еще еще.
Лучший способ отслеживать за тек.позицией в НД (в том числе при перечитке) - запоминать ID. Я это делаю часто в тэге соотв. датасета.
Тогда фича переоткрытия будет выглядеть примерно так:function TdmCrime.DB_ReOpenQuery(DS: TADOQuery; LocRec: true): boolean;
begin
result := true;
with DS do
try
if Active then Close;
Open;
if LocRec and (Tag>0) then
Locate(Fields[0].FieldName,[]);
except
result := false;
end;
DS.Tag := 0;
end;
← →
Ega23 © (2005-09-23 11:04) [7]ARAIR, где-то с месяц назад ты сам вопрос по букмаркам задавал
и тебе объясняли, что закрытие датасета ведет к потере смысла букмарка в нем
То другое было. Там я компонент ДБшный писал.
А эта функция - не моя.
← →
Ega23 © (2005-09-23 11:05) [8]Тогда фича переоткрытия будет выглядеть примерно так:
Это только если ключевое поле - первое по-порядку. Что далеко не всегда бывает.
← →
msguns © (2005-09-23 11:07) [9]>Ega23 © (23.09.05 11:05) [8]
>Это только если ключевое поле - первое по-порядку. Что далеко не всегда бывает.
Надо, чтоб так было. Сделать это местным стандартом программирования.
← →
Danilka © (2005-09-23 11:11) [10][6] msguns © (23.09.05 11:02)
А если ключ составной? :)
← →
msguns © (2005-09-23 11:16) [11]>Danilka © (23.09.05 11:11) [10]
>А если ключ составной? :)
А что, уникальный идентификатор включают в составной ключ ?
Если НД без ID, как, например при агрегатніх запросах, то в тэге 0, а позиционирование делать как надо уже после переоткрытия в соотв. месте кода.
Правда, тут сразу возникает вопрос: а зачем перепозиционировать агрегатные запросы, ведь они только читаемые ?
← →
msguns © (2005-09-23 11:16) [12]>Danilka © (23.09.05 11:11) [10]
>А если ключ составной? :)
А что, уникальный идентификатор включают в составной ключ ?
Если НД без ID, как, например при агрегатніх запросах, то в тэге 0, а позиционирование делать как надо уже после переоткрытия в соотв. месте кода.
Правда, тут сразу возникает вопрос: а зачем перепозиционировать агрегатный НД, ведь он только читаемый ?
← →
Ega23 © (2005-09-23 11:46) [13]Надо, чтоб так было. Сделать это местным стандартом программирования.
Нельзя. Есть, скажем, "Информационно-отчётная система", которая строится исключительно из базы. Т.е. в таблице прописаны названия полей со всеми атрибутами, которые видны в гриде. Грид строит колонки по принципу from Fields[0] to пока не кончатся записи. Остальные поля, в том числе и ключевое, в гдиде не видны.
В принципе, можно в данную функцию передавать параметры DataSet.Locate - поле (или список полей) и variant-значение (или VarArray).
Проблема данного подхода заключается в том, что параметр типа Variant не может иметь значений по-умолчанию. А надо. Чтобы либо использовать позиционирование, либо нет.
← →
isasa © (2005-09-23 11:58) [14]:)
msguns © (23.09.05 11:16) [11]
А если база реплицируемая, т.е.ID: TGUID;
← →
Desdechado © (2005-09-23 12:51) [15]Ega23 © (23.09.05 11:04) [7]
> То другое было. А эта функция - не моя.
Почему же другое? Букмарк и в Африке букмарк. И в чужой функции тоже :)
← →
Ega23 © (2005-09-23 13:59) [16]Почему же другое? Букмарк и в Африке букмарк. И в чужой функции тоже :)
Так я и написал в [0] на подозрения... :о)
← →
k2 © (2005-09-23 14:20) [17]малюсенький вопросик вдогонку по букмаркам:
а если датасет отфильтрован и обращаемся к букмарке, запись которой не попала в фильтрованную часть што получится?
Страницы: 1 вся ветка
Текущий архив: 2005.11.06;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.222 c