Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.52 MB
Время: 0.032 c
1-1129199943
Aleksandr.
2005-10-13 14:39
2005.11.06
Объясните мне, в чем проблема уничтожения терминированной нити?!


14-1129572358
Bogdan1024
2005-10-17 22:05
2005.11.06
Transact-SQL за 2 дня


1-1129549303
Trifle
2005-10-17 15:41
2005.11.06
Поменять надписи на кнопках MessageDlg?


14-1129553071
Игорь Шевченко
2005-10-17 16:44
2005.11.06
Почти по Екклезиасту...


14-1129646450
Fin
2005-10-18 18:40
2005.11.06
Опять про миранду.