Конференция "KOL" » Как уничтожить PDataSource [Delphi, Windows]
 
  • hornet (06.12.07 09:57) [0]
    Добрый день.

    Есть проца:


    function TabNum(st:kolstring): kolstring;
    var
     _D    : PDataSource;
     _S    : PSession;
     _Q    : PQuery;

    begin
    _D := NewDataSource('Provider=OraOLEDB.Oracle.1;Password=pass;Persist Security Info=True;User ID=user;Data Source=BD');
    _S := NewSession(_D);
    _Q := NewQuery(_S);
     TRY
       _Q.Text := 'select * from table t where t.c1='''+st+'''' and rownum=1;
       _Q.Open;
       _Q.First;

       while not _Q.Eof do
       begin
            res:= Q.SField[4];
         _Q.Next;
       end;
       _Q.Close;
     FINALLY
       _Q.Free;
       _S.Free;
       _D.Final; //(вот здесь ошибка "OLE DB error 80040E05") - типа это обьект открыт еще

       _D := nil;
       _S := nil;
       _Q := nil;
     END;

     TabNum:=res;
    end;



    Если этого не делать, тогда все ок - но память при каждом вызове увеличивается :(
    Как его убивать корректно ?

    Delphi 7 + KOL версия 2.70
  • hornet (10.12.07 16:34) [1]
    Неужели никто не работал с БД в KOL ?


    > Есть проца:


    Не проца естественно, а функция :)
  • ANTPro © (10.12.07 17:05) [2]
    > [0] hornet   (06.12.07 09:57)
    > _D.Final;

    Почему не Free как всегда? А вообще может надо отключиться от сервера

    > [1] hornet   (10.12.07 16:34)
    > Неужели никто не работал с БД в KOL ?

    Я не рискнул :)
  • hornet (11.12.07 08:15) [3]

    > Почему не Free как всегда?

    Сорри, Final считать равным Free. :))


    > А вообще может надо отключиться от сервера

    А как отключатся ?


    > Я не рискнул :)

    Так я только для отчетов KOL применяю. :)
  • ANTPro © (11.12.07 18:31) [4]
    > [0] hornet   (06.12.07 09:57)
    >   _Q.Free;
    >   _S.Free;
    >   _D.Final; //(вот здесь ошибка «OLE DB error 80040E05»)
    > — типа это обьект открыт еще
    >
    >   _D := nil;
    >   _S := nil;
    >   _Q := nil;

    Что если заменить на это? (так сделано в демке)

     _D.Free;
     _S := nil;
     _Q := nil;

  • ANTPro © (11.12.07 18:45) [5]
    Заглянул в деструктор PDataSource, там стоит авто разрушение обьектов которые были прицепленны к нему :)
    Хотя, это OLE DB error это не уберет.
  • hornet (12.12.07 16:01) [6]

    >
    > Что если заменить на это? (так сделано в демке)
    >
    >  _D.Free;
    >  _S := nil;
    >  _Q := nil;
    >

    Я так уже пробовал ... не канает :(

    > ...это OLE DB error это не уберет.

    Точно не убирает :(
  • Jon © (12.12.07 16:22) [7]
    Reverse the order:


     finally
       _Q.Free;
       _S.Free;
       _D := nil;
       _D.Free;
     end;

  • Дмитрий К © (12.12.07 16:23) [8]
    Попробуйте объявить символ
    OLD_REFCOUNT

  • Vladimir Kladov © (12.12.07 18:06) [9]
    2Jon: if to assign nil to _D, _D.Free will do nothing. Message will disappear but leak will be there.
  • Vladimir Kladov © (12.12.07 18:08) [10]
    Я очень советую попробовать KOLODBC. Драйверы ODBC могут быть кривоваты, и бывает нужно искать действительно рабочий. Зато сам интрефейс с драйвером прост.
  • hornet (29.12.07 09:30) [11]
    По совету решил попробовать KOLODBC (http://kolmck.net/Components/db/KOLOdbc.zip).
    Положил KOLOdbc.pas туда же где лежит KOL.

    Вместе c библиотекой идет примерчик KOLODBC. При попытке компиляции ругается, что нет модуля
    [Fatal Error] Unit1.pas(8): File not found: 'ODBCQuery.dcu'



    Ну ладно, модуль не так называется. Поменял ODBCQuery на KOLOdbc.
    В Project - Options - Directories/Conditionals параметр Search path поставил путь к KOL.

    К сожалению, это ни к чему хорошему не привело :(
    [Error] Unit1.pas(57): Undeclared identifier: 'PODBCDatabase'



    с чего это ? модуль то подключен!
  • Vladimir Kladov © (29.12.07 12:23) [12]
    а внутрь посмотреть? Это дуальный модуль, для KOL и VCL. Опцию включить надо.
  • Артем (06.03.08 13:39) [13]
    Что-то начало модуля KOLOdbc сразу напрягает.
    uses Windows, Classes, {$IFDEF KOL}KOL, KOLmath, err
                          {$ELSE} SysUtils, Forms, Db, math{$ENDIF};


    Классы? Хотел консольную программку маленькую сделать..

    Но и KOLEdb тоже, мягко говоря, странный. Кстати, PDataSource.Final как раз не вызовет исключения. А вот PDataSource.Free вызывает оное. Если я все правильно понял, деструктор TDataSource должен уничтожить все сессии. А при вызове деструктора сессий вызываются и деструкторы запросов.

    А может кто-нибудь пролить свет, в какой момент должна закрываться сессия в БД? Устанавливается сессия при создании TDataSource (конструктором, стало быть). В деструкторе TDataSource наблюдается следующее:
       CheckOLE( fIDBInitialize.UnInitialize );


    Вот этот вот fIDBInitialize.UnInitialize и заявляет, что объект еще используется. И действительно, сессия-то установлена еще. Или данная операция как раз и должна сессию завершить? Но не может, т.к. что-то ей мешает?

    Простите, что сумбурно.. Но хочется сделать маленькое и шустрое приложение с загрузкой данных из оракла, на некоммерческих компонентах. Правда ODBC далеко не шустро..
  • Аид (22.05.08 06:30) [14]
    Реально с классами... весь смысл КОЛ теряется... сразу минимум 400Кб в ехе внедряется... :( есть другие варианты доступа к БД? Интересует PostGreSQL
  • Dy1 (22.08.09 12:25) [15]
    таки никто не знает как решить проблему?
    Прога много чего делает и нужно добавить туда БД. Модуль KOLEdb используется для обращения к .mdb, KOLComObj - для сжатия БД (не знаю можно ли сэкономить 100 кБт, которые даёт KOLComObj). Проблема в том, что функция сжатия не отрабатывает из-за ошибки освобождения PDataSource. Помогите пожалуйста, работа стоит
  • Dy1 (22.08.09 12:49) [16]
    или переписывать на вцл и получать трёхметровый ехе?

    > Драйверы ODBC могут быть кривоваты, и бывает нужно искать действительно рабочий
    не катит. Не хочу таскать с собой рабочие драйверы.

    Есть у кого-н рабочие демки сжатия mdb и работы с этой БД?
  • Dy1 (13.09.09 18:44) [17]
    OLD_REFCOUNT не помог.
    ODBC, который встроенный, не запустился.

    Сжатие написано, но теперь не отрабатывает из-за PDataSource - либо ошибка, либо "база открыта". Вопрос тот же - как уничтожить, зарыть и поставить памятник?
  • Vladimir Kladov © (13.09.09 20:01) [18]
    Их надо не с собой таскать, а выяснить, с какой версией какого софта они идут правильные (чаще всего какой mdac накатить, или клиент sql)
  • Dy1 (18.09.09 13:51) [19]
    рабочий драйвер так и не нашёл (после проведённого опроса выяснилось, что никто KOLEdb не пользуется и почти никто - KOLODBC).
    Нашёл интересную статью про особенности Делфи в области интерфейсов :/

    Проблему решил почти случайно. Пока всё отлично (не считая изначально отсутствующих BLOB в KOLEdb).
    Итак...
  • Dy1 (18.09.09 14:08) [20]
    в программе
    uses ...KOLEdb, JRO_TLBKOL; // работа с мдб и сжатие
     JRO_TLB нашёл в инете (обрезок, где только сжатие). Работает хорошо, в отличие от оригинала.

    Не помню что было, поэтому привожу кусочек
    unit JRO_TLBKOL;
    interface
    uses ActiveKOL, ADODB_TLBKOL, KOLComObj;



    следующие изменения:
    в KOLEdb убрал закомментированный код,
    в TSession.Destroy поменял fQueryList.Free на Free_And_Nil(fQueryList),
    в TDataSource.Destroy аналогично - Free_And_Nil(fSessions).
     Вроде бы всё.

    Теперь код
    var DS: PDataSource;
       SS: PSession;
       QR: PQuery;

    procedure TForm1.KOLForm1FormCreate(Sender: PObj);
    var
     Src,Dest: WideString;
     V: JetEngine;
    begin
     DS := NewDataSource( 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;' +
       'Data Source=' + GetStartDir + 'dat.mdb;' +
       'Mode=Share Deny None;' +
       'Extended Properties=\"\";' +
       'Locale Identifier=1033;' +
       'Persist Security Info=False;' );
     SS := NewSession( DS );
     QR := NewQuery( SS );
     QR.Text := 'select * from topt';
     QR.Open;
    //  DS.Destroy; на нём отлаживал, т.к. прежде фри не вызывался
     DS.Free;
     DS := nil;

     Src := Provider + GetStartDir + 'dat.mdb;';
     Dest := Provider + GetStartDir + 'd.mdb;';
     OleInit;
     try
       v := CoJetEngine.Create;
       v.CompactDatabase(Src, Dest);
     finally
       v := Nil;
       OleUnInit;
     end;


    отлично работает, исчезли утечки...

    Я думаю, дело в том, что нужно было приравнять списки запросов и сессий нилам и тогда интерфейс нормально освобождается
 
Конференция "KOL" » Как уничтожить PDataSource [Delphi, Windows]
Есть новые Нет новых   [134431   +11][b:0][p:0.003]