Секреты Delphi. Мониторинг SQL-запросов при работе с ADO-компонентами

Не секрет, что приложения баз данных составляют довольно большую долю всех вновь разрабатываемых приложений. Ни одна информационная система не может быть создана без соединения с той или иной СУБД. В первых версиях нам предлагался давно устаревший, но все еще успешно использующийся Borland Database Engine (BDE). Одним из альтернативных способов доступа к источникам данных стали компоненты ADO.

Хотя в новых версиях Delphi добавлены более современные компоненты dbExpress, а также огромное количество компонент сторонних производителей, компоненты ADO все еще заслуживают внимания. Из-за простоты использования, интеграции со средой разработки (в поставке Delphi Enterpise), а также довольно высокой скорости работы имеет смысл их использовать, если не планируется переходить на мультиплатформенную разработку.
Первой из рассматриваемых компонент будет TADOConnection. Не будем останавливаться на подробном процессе настройки соединения — информацию об этом можно прочитать и в help'е. Хочется отметить отсутствие мониторинга SQL-запросов при работе с ADO-компонентами. А при отладке программ данная функция будет далеко не последней. Особенно при работе с параметрическими запросами. Мониторинг позволяет визуально отследить, что же в действительности посылается серверу базы данных. Особую актуальность этот режим приобретает на компьютере заказчика. Delphi IDE с собой таскать ох как не хочется. Да и не на всяком компьютере развернешь эту среду разработки. Для реализации функции мониторинга напишем пару методов на события WillExecute и ExecuteComplete компоненты TADOConnection.

fExecuteTime     :dword;
...

procedure TDM.dbConnectionWillExecute(Connection: TADOConnection;
  var CommandText: WideString; var CursorType: TCursorType;
  var LockType: TADOLockType; var CommandType: TCommandType;
  var ExecuteOptions: TExecuteOptions; var EventStatus: TEventStatus;
  const Command: _Command; const Recordset: _Recordset);
var
  i,j:integer;
  infoStr:String;
  tmpParameters:Parameters;
begin
  if gDebugMode then
    MonitorEvent('WillExecute.. ',[]);
  fExecuteTime:=GetTickCount;
  if gSqlMonitor and gDebugMode then
  begin
    MonitorEvent(CommandText,['']);
    if Assigned(Recordset) then
    begin
      for i := 0 to (dbConnection.DataSetCount-1) do
       if Assigned(dbConnection.DataSets[i].Recordset)
        and (Recordset = dbConnection.DataSets[i].Recordset) then
        if (dbConnection.DataSets[i] is TADODataSet)
          and (TADODataSet(dbConnection.DataSets[i]).Parameters.Count > 0) then
          for j:=0 to TADODataSet(dbConnection.DataSets[i]).Parameters.Count - 1 do
          begin
            infoStr:='P['+IntToStr(j)+'] '
            + TADODataSet(dbConnection.DataSets[i]).Parameters.Items[j].Name+' = ';
            if Not VarisNull(TADODataSet(dbConnection.DataSets[i]).
               Parameters.Items[j].Value) then
              infoStr:=infoStr
              + String(TADODataSet(dbConnection.DataSets[i]).Parameters.Items[j].Value)
            else
              infoStr:=infoStr + 'Null';
            MonitorEvent(infoStr,['']);
          end;
    end;
    if Assigned(Command) then
    begin
      tmpParameters:=Command.Get_Parameters;
      if (tmpParameters.Count > 0) then
        for j:=0 to tmpParameters.Count - 1 do
        begin
          infoStr:=tmpParameters.Item[j].Name+' = ';
          if Not VarisNull(tmpParameters.Item[j].Value) then
            infoStr:=infoStr + String(tmpParameters.Item[j].Value)
          else
            infoStr:=infoStr + 'Null';
          MonitorEvent(infoStr,['']);
        end
    end;
    MonitorEvent('',['']);
  end;
end;

procedure TDM.dbConnectionExecuteComplete(Connection: TADOConnection;
  RecordsAffected: Integer; const Error: Error;
  var EventStatus: TEventStatus; const Command: _Command;
  const Recordset: _Recordset);
begin
  Self.fExecuteTime:=GetTickCount-Self.fExecuteTime;
  if gDebugMode then
    MonitorEvent('Execute time: ' + FloatToStr(Self.fExecuteTime / 1000) + ' s.',[]);
end;

Для управления режимом мониторинга и отладки введены глобальные переменные gSqlMonitor и gDebugMode. Функция вывода окна мониторинга MonitorEvent не приводится, так как написать ее очень просто. 

Пример реализации окна SQL-мониторинга показан на рисунке.



Сергей Бердачук, Berdachuk@tut.by
http://bs_elbis.at.tut.by 



Опубликовал admin
12 Авг, Четверг 2004г.



Программирование для чайников.