Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2005年05月04日] [更新 2013年03月22日] Delphi サンプルプログラム集
580_ADO で JET, Paradox テーブル一覧表示
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro + Msjet40.dll 4.00.9756.0
580_ADO_TableList.zip [1,867 KB] 2013年03月22日版 (EXE 同梱)



  • 2010年05月22日
  • 動作確認環境の変更と記事構成の修正と変更等





ADO によるデータベースのテーブル一覧


ADO (Micrsoft ActiveX Data Object)を 使用して,JETデータベース (mdb ファイル) と Paradox のテーブルの一覧を表示するサンプルプログラムです.SQL 文の実行もできるようにしています.
Paradox データベースは,BDE がインストールされていない環境でも動作します.テーブルの作成やインデックの機能を追加したサンプルを作成しておけば,開発には便利ですが,そのようなユーティリティをネット上で提供されている方もいます.また,テーブルやインデックスの設計には Delphi のデータベースデスクトップ等を使用することもできます.
利用にあたっては,[568_ADO による Paradox データベース接続] の記事内容も確認してください.

以下のサンプルコードでデータを編集して更新する際に,データの構造によっては,
  • 更新可能なクエリであることが必要です
  • クエリが複雑すぎます
のエラーが発生することがあります.その場合には,Priamry Key (一次キー) の作成とか,取得する項目数を少なくしたクエリを実行することで対応します.
ただし,「更新可能なクエリであることが必要です」のエラーは,SQL 文によっては,これ以外の原因で発生する場合があります.


以下は,サンプルプログラム集の ADO 関係の記事へのリンクです.





01_JET データベースのテーブル一覧


拡張子が .mdb の JET データベースの表の一覧を取得して表示するサンプルです.mdb はマイクロソフトの Access というデータベースソフトで使用されているデーベースのファイルです.


図1
設計時画面
図2
実行例
  • mdb ファイルを開いてテーブル名をクリックしたところ
  • これは添付のデータベース
図3
SQL 文も作成して実行可能

リスト1
JET データベース (mdb ファイル) のテーブル一覧表示
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, StdCtrls, Grids, DBGrids, ExtCtrls, Buttons, Menus,
  DBCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    menuFile: TMenuItem;
    menuAccessOpen: TMenuItem;
    menuSepareter1: TMenuItem;
    menuClose: TMenuItem;
    StatusBar1: TStatusBar;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Splitter1: TSplitter;
    Splitter2: TSplitter;
    Splitter3: TSplitter;
    ListView1: TListView;
    ListView2: TListView;
    Memo1: TMemo;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    OpenDialog1: TOpenDialog;
    SpeedButton1: TSpeedButton;
    DBNavigator1: TDBNavigator;
    SQL1: TMenuItem;
    OpenSQL: TMenuItem;
    SaveSQL: TMenuItem;
    SaveDialog1: TSaveDialog;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure menuAccessOpenClick(Sender: TObject);
    procedure menuCloseClick(Sender: TObject);
    procedure ListView1Click(Sender: TObject);
    procedure ListView1Editing(Sender: TObject; Item: TListItem;
      var AllowEdit: Boolean);
    procedure SpeedButton1Click(Sender: TObject);
    procedure OpenSQLClick(Sender: TObject);
    procedure SaveSQLClick(Sender: TObject);
    procedure Panel1Resize(Sender: TObject);
  private
    { Private 宣言 }
    DBFileDir  : String;
    SQLFileDir : String;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses FileCtrl;

{$R *.dfm}

//=============================================================================
//  FormCreate時に各種初期設定
//  ADOConnecton1,ADOQuery1はFormに配置しデフォルトの状態で使用
//  それ以外の設定はこのサンプルコード内で行っている
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ReadOnly  := True;
  ListView2.ReadOnly  := True;
  ListView1.RowSelect := True;
  ListView2.RowSelect := True;

  //ADO等DB関係の設定
  ADOConnection1.Mode           := cmReadWrite;
  ADOConnection1.KeepConnection := False;
  ADOConnection1.Connected      := False;
  ADOConnection1.LoginPrompt    := False;
  ADOQuery1.Connection          := ADOConnection1;
  ADOQuery1.Prepared            := True;

  //サンプルデータベースファイルのあるフォルダ
  DBFileDir := ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'Data';
  //SQL文保存先フォルダ
  SQLFileDir := ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'SQL';
end;

//=============================================================================
//  フォームを閉じたら接続を切断
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ADOConnection1.Connected := False;
end;

//=============================================================================
//  メインメニューの[閉じる]
//=============================================================================
procedure TForm1.menuCloseClick(Sender: TObject);
begin
  Close;
end;

//=============================================================================
//  メインメニューの[開く]
//  ファイル選択ダイアログを表示しデータベースファイル(mdb)を選択
//=============================================================================
procedure TForm1.menuAccessOpenClick(Sender: TObject);
var
  TableList  : TStrings;
  i          : Integer;
  AItem      : TListItem;
begin
  OpenDialog1.Filter := 'JETデータベースファイル(*.mdb)|*.mdb';

  if OpenDialog1.InitialDir = '' then OpenDialog1.InitialDir := DBFileDir;

  if OpenDialog1.Execute then begin
    ADOQuery1.Close;
    ADOConnection1.Connected := False;
    Memo1.Clear;

    with ADOConnection1 do begin
      Provider := 'Microsoft.Jet.OLEDB.4.0';
      //接続文字列
      ConnectionString := 'Data Source=' + OpenDialog1.FileName;

      //ListView1にテーブルの一覧を表示
      ListView1.Clear;
      ListView2.Clear;
      TableList := TStringList.Create;
      try
        ADOConnection1.GetTableNames(TableList);
        for i := 0 to TableList.Count - 1 do begin
          AItem := ListView1.Items.Add;
          AItem.Caption := TableList[i];
        end;

        //Captionにファイル名,ステータスバーにテーブル数を表示
        Self.Caption              := Caption + ' '+OpenDialog1.FileName;
        StatusBar1.Panels[0].Text := ' '+IntToStr(TableList.Count) + ' Tables';
        StatusBar1.Panels[1].Text := '';
      finally
        TableList.Free;
      end;
    end;
  end;
end;

//=============================================================================
//  メインメニュー[SQL][開く]
//=============================================================================
procedure TForm1.OpenSQLClick(Sender: TObject);
begin
  OpenDialog1.InitialDir := SQLFileDir;
  OpenDialog1.Filter     := 'SQLファイル (*.SQL)|*.SQL;';

  if OpenDialog1.Execute then begin
    SQLFileDir := ExtractFilePath(OpenDialog1.FileName);
    try
      Memo1.Clear;
      Memo1.Lines.LoadFromFile(OpenDialog1.FileName);
    except
    end;
  end;
end;

//=============================================================================
//  メインメニュー[SQL][名前を付けて保存]
//=============================================================================
procedure TForm1.SaveSQLClick(Sender: TObject);
begin
  SaveDialog1.InitialDir := SQLFileDir;
  SaveDialog1.Filter     := 'SQLファイル (*.SQL)|*.SQL;';
  SaveDialog1.DefaultExt := 'SQL';

  if SaveDialog1.Execute then begin
    SQLFileDir := ExtractFilePath(SaveDialog1.FileName);
    try
      Memo1.Lines.SaveToFile(SaveDialog1.FileName);
    except
    end;
  end;
end;

//=============================================================================
//  テーブル名一覧表示用のListViewsの項目をクリック
//  項目のテーブルの全データを表示するSQL文を作成して実行
//  ListViewにテーブルの項目をリスト
//  テーブルとは,mdbの場合はmdb内の選択した表
//=============================================================================
procedure TForm1.ListView1Click(Sender: TObject);
var
  indx     : Integer;
  SQLSL    : TStringList;
  FieldSL  : TStringList;
  i        : Integer;
  AItem    : TListItem;
  StatusStr: String;
begin
  if ListView1.Items.Count < 1 then exit;

  Screen.Cursor := crSQLWait;
  indx          := ListView1.ItemIndex;
  StatusStr     := '';
  try
    if indx>=0 then begin
      SQLSL   := TStringList.Create;
      FieldSL := TStringList.Create;
      FieldSL.Clear;
      ADOQuery1.Close;
      try
        SQLSL.Add('select * from '+ ListView1.Items[indx].Caption);
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Text := SQLSL.Text;
        ADOQuery1.Open;
        ADOQuery1.GetFieldNames(FieldSL);
        //ListVeiw2に項目名のリストを作成
        ListView2.Clear;
        for i := 0 to FieldSL.Count - 1 do begin
          AItem := ListView2.Items.Add;
          AItem.Caption := FieldSL[i];
        end;
        StatusStr := '   レコード数 : ' + IntToStr(ADOQuery1.RecordCount);

      finally
        SQLSL.Free;
        FieldSL.Free;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  StatusBar1.Panels[1].Text := StatusStr;
end;

//=============================================================================
//  [SQL実行]
//  Memo1に入力したSQL文を実行する
//  当然であるが更新不可能なデータに対してはExecSQLはエラーとなる
//  ExecSQL実行後は,再度テーブル表示を実行する必要あり
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  RecNoStr : String;
begin
  ADOQuery1.Close;
  RecNoStr := '';
  Screen.Cursor := crSQLWait;

  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Assign(Memo1.Lines);

    //選択クエリーかどうかをSELECTがあるかで判定(何かプロパティがあったような)
    if AnsiPos('SELECT',UpperCase(Memo1.Text)) <> 0 then begin
      try
        ADOQuery1.Open;
        RecNoStr := '   レコード数 : ' + IntToStr(ADOQuery1.RecordCount);
       except
         raise;
      end;
    end else begin
      try
        ADOQuery1.ExecSQL;
      except
        raise;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  StatusBar1.Panels[1].Text := RecNoStr;
end;

//=============================================================================
//  ListViewの幅が変わったらカラムの表示幅も変更
//=============================================================================
procedure TForm1.Panel1Resize(Sender: TObject);
begin
  ListView1.Column[0].Width := ListView1.ClientWidth;
  ListView2.Column[0].Width := ListView2.ClientWidth;
end;

//=============================================================================
//  テーブル名,項目名は編集不可
//=============================================================================
procedure TForm1.ListView1Editing(Sender: TObject; Item: TListItem;
  var AllowEdit: Boolean);
begin
  AllowEdit := False;
end;

end.




02_Paradox データベースのテーブル一覧


Paradox データベースのテーブル一覧を表示するサンプルです.Paradox は指定したフォルダがデータベースとなります.
約 1 万レコードの Pardox のデータでテストしたところ,一次インデックスも二次インデックスもなし,つまり読出し専用で検索するクエリを実行したところ,約 300 ms,一次インデックスを設定して同じクエリでは 約 3 秒もかかる例がありました.BED なしで動作するのは魅力的ですが,実際の利用では十分な確認が必要でしょう.


図4
設計時画面
図5
実行例
  • データベース (フォルダ) を指定して表を開いてところ
  • これは添付の Test という表

リスト2
Paradox データベースのテーブル一覧表示
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, StdCtrls, Grids, DBGrids, ExtCtrls, ComCtrls,
  Buttons, Menus, DBCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    menuFile: TMenuItem;
    menuParadoxOpen: TMenuItem;
    menuSepareter1: TMenuItem;
    menuClose: TMenuItem;
    StatusBar1: TStatusBar;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Splitter1: TSplitter;
    Splitter2: TSplitter;
    Splitter3: TSplitter;
    ListView1: TListView;
    ListView2: TListView;
    Memo1: TMemo;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    OpenDialog1: TOpenDialog;
    SpeedButton1: TSpeedButton;
    DBNavigator1: TDBNavigator;
    SQL1: TMenuItem;
    OpenSQL: TMenuItem;
    SaveSQL: TMenuItem;
    SaveDialog1: TSaveDialog;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure menuParadoxOpenClick(Sender: TObject);
    procedure menuCloseClick(Sender: TObject);
    procedure ListView1Click(Sender: TObject);
    procedure ListView1Editing(Sender: TObject; Item: TListItem;
      var AllowEdit: Boolean);
    procedure SpeedButton1Click(Sender: TObject);
    procedure OpenSQLClick(Sender: TObject);
    procedure SaveSQLClick(Sender: TObject);
    procedure Panel1Resize(Sender: TObject);
  private
    { Private 宣言 }
    DBFileDir  : String;
    SQLFileDir : String;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses FileCtrl;

{$R *.dfm}

//=============================================================================
//  FormCreate時に各種初期設定
//  ADOConnecton1,ADOQuery1はFormに配置しデフォルトの状態で使用
//  それ以外の設定はこのサンプルコード内で行っている
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ReadOnly  := True;
  ListView2.ReadOnly  := True;
  ListView1.RowSelect := True;
  ListView2.RowSelect := True;

  //ADO等DB関係の設定
  ADOConnection1.Mode           := cmReadWrite;
  ADOConnection1.KeepConnection := False;
  ADOConnection1.Connected      := False;
  ADOConnection1.LoginPrompt    := False;
  ADOQuery1.Connection          := ADOConnection1;
  ADOQuery1.Prepared            := True;

  //サンプルデータベース(Paradoxではフォルダ)
  DBFileDir := ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'Data';
  //SQL文保存先フォルダ
  SQLFileDir := ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'SQL';
end;

//=============================================================================
//  フォームを閉じたら接続を切断
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ADOConnection1.Connected:=False;
end;

//=============================================================================
//  メインメニューの[閉じる]
//=============================================================================
procedure TForm1.menuCloseClick(Sender: TObject);
begin
  Close;
end;

//=============================================================================
//  メインメニューの[開く]
//  フォルダの選択ダイアログを表示してフォルダを選択する
//=============================================================================
procedure TForm1.menuParadoxOpenClick(Sender: TObject);
var
  TableList : TStrings;
  i         : Integer;
  AItem     : TListItem;
begin
  //DBFileDirは初期フォルダ名
  if SelectDirectory('Paradoxデータベース選択', '', DBFileDir) then begin
    ADOQuery1.Close;
    ADOConnection1.Connected := False;
    Memo1.Clear;

    with ADOConnection1 do begin
      Provider := 'Microsoft.Jet.OLEDB.4.0';
      //接続文字列
      ConnectionString := 'Data Source=' + DBFileDir +
                          ';Extended Properties="Paradox 5.x;"';

      //ListView1にテーブルの一覧を表示
      ListView1.Clear;
      ListView2.Clear;
      TableList := TStringList.Create;
      try
        ADOConnection1.GetTableNames(TableList);
        for i := 0 to TableList.Count - 1 do begin
          AItem := ListView1.Items.Add;
          AItem.Caption := TableList[i];
        end;

        //Captionにフォルダ名(データベース名),ステータスバーにテーブル数表示
        Self.Caption              := Caption + ' ' + DBFileDir;
        StatusBar1.Panels[0].Text := ' ' + IntToStr(TableList.Count) + ' Tables';
        StatusBar1.Panels[1].Text := '';
      finally
        TableList.Free;
      end;
    end;

    //Windows Vista,Windows 7ではこれがないとSQLが正常に実行されない
    //ADOConnectionがTrueになってから設定しないと無効
    ADOQuery1.ConnectionString := ADOConnection1.ConnectionString;
  end;
end;

//=============================================================================
//  メインメニュー[SQL][開く]
//=============================================================================
procedure TForm1.OpenSQLClick(Sender: TObject);
begin
  OpenDialog1.InitialDir := SQLFileDir;
  OpenDialog1.Filter     := 'SQLファイル (*.SQL)|*.SQL;';

  if OpenDialog1.Execute then begin
    SQLFileDir := ExtractFilePath(OpenDialog1.FileName);
    try
      Memo1.Clear;
      Memo1.Lines.LoadFromFile(OpenDialog1.FileName);
    except
    end;
  end;
end;

//=============================================================================
//  メインメニュー[SQL][名前を付けて保存]
//=============================================================================
procedure TForm1.SaveSQLClick(Sender: TObject);
begin
  SaveDialog1.InitialDir := SQLFileDir;
  SaveDialog1.Filter     := 'SQLファイル (*.SQL)|*.SQL;';
  SaveDialog1.DefaultExt := 'SQL';

  if SaveDialog1.Execute then begin
    SQLFileDir := ExtractFilePath(SaveDialog1.FileName);
    try
      Memo1.Lines.SaveToFile(SaveDialog1.FileName);
    except
    end;
  end;
end;

//=============================================================================
//  テーブル名一覧表示用のListViewsの項目をクリック
//  項目のテーブルの全データを表示するSQL文を作成して実行
//  ListViewにテーブルの項目をリスト
//  テーブルとは,Paradoxの場合はフォルダ内の拡張子がdbのファイル
//=============================================================================
procedure TForm1.ListView1Click(Sender: TObject);
var
  indx     : Integer;
  SQLSL    : TStringList;
  FieldSL  : TStringList;
  i        : Integer;
  AItem    : TListItem;
  StatusStr: String;
begin
  if ListView1.Items.Count < 1 then exit;

  Screen.Cursor := crSQLWait;
  indx          := ListView1.ItemIndex;
  StatusStr     := '';

  try
    if indx>=0 then begin

      SQLSL   := TStringList.Create;
      FieldSL := TStringList.Create;
      FieldSL.Clear;
      ADOQuery1.Close;
      try
        SQLSL.Add('select * from '+ ListView1.Items[indx].Caption);
        ADOQuery1.SQL.Clear;
        ADOQuery1.SQL.Text := SQLSL.Text;
        ADOQuery1.Open;
        ADOQuery1.GetFieldNames(FieldSL);
        //ListVeiw2に項目名のリストを作成
        ListView2.Clear;
        for i := 0 to FieldSL.Count - 1 do begin
          AItem := ListView2.Items.Add;
          AItem.Caption := FieldSL[i];
        end;
        StatusStr := '   レコード数 : ' + IntToStr(ADOQuery1.RecordCount);

      finally
        SQLSL.Free;
        FieldSL.Free;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  StatusBar1.Panels[1].Text := StatusStr;
end;

//=============================================================================
//  [SQL実行]
//  Memo1に入力したSQL文を実行する
//  当然であるが更新不可能なデータに対してはExecSQLはエラーとなる
//  ExecSQL実行後は,再度テーブル表示を実行する必要あり
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  RecNoStr : String;
begin
  ADOQuery1.Close;
  RecNoStr := '';
  Screen.Cursor := crSQLWait;

  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Assign(Memo1.Lines);

    //選択クエリーかどうかをSELECTがあるかで判定(何かプロパティがあったような)
    if AnsiPos('SELECT',UpperCase(Memo1.Text)) <> 0 then begin
      try
        ADOQuery1.Open;
        RecNoStr := '   レコード数 : ' + IntToStr(ADOQuery1.RecordCount);
       except
         raise;
      end;
    end else begin
      try
        ADOQuery1.ExecSQL;
      except
        raise;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  StatusBar1.Panels[1].Text := RecNoStr;
end;

//=============================================================================
//  ListViewの幅が変わったらカラムの表示幅も変更
//=============================================================================
procedure TForm1.Panel1Resize(Sender: TObject);
begin
  ListView1.Column[0].Width := ListView1.ClientWidth;
  ListView2.Column[0].Width := ListView2.ClientWidth;
end;

//=============================================================================
//  テーブル名,項目名は編集不可
//=============================================================================
procedure TForm1.ListView1Editing(Sender: TObject; Item: TListItem;
  var AllowEdit: Boolean);
begin
  AllowEdit:=False;
end;

end.




03_SQL パラメータの設定方法


ADO で,JET プロバイダ接続した場合,BDE で使用していた SQL 文とは文法が少し違ってきます.ここでは日付の場合に限って例を示しています.
BDE で Paradox に接続する時は,SQL のパラメータの指定に ParamByName が使用できますが,ADO の SQL ではこのメソッドを直接使用することはできません.また,SQL に直接日付を書く時も書式が違います.
以下のボタンクリックのコードは,全て同じ結果となります.


リスト3
JET プロバイダでの日付関係の SQ L文
//=============================================================================
//  実行時にSQLでパラメータを使用1
//  Parametersのインデックスを使う
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if ADOConnection1.Connected = False then exit;

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日>=:DATE1 AND 就労日<=:DATE2 ');

    ADOQuery1.Parameters[0].Value := StrToDate('1998/01/01');
    ADOQuery1.Parameters[1].Value := StrToDate('1998/01/31');

    ADOQuery1.Open;
  except
    raise;
  end;
end;

//=============================================================================
//  実行時にSQLでパラメータを使用2
//  パラメータの名前を使い日付型で代入
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  if ADOConnection1.Connected = False then exit;

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日>=:DATE1 AND 就労日<=:DATE2 ');

    ADOQuery1.Parameters.ParamByName('DATE1').Value := StrToDate('1998/1/01');
    ADOQuery1.Parameters.ParamByName('DATE2').Value := StrToDate('1998/1/31');

    ADOQuery1.Open;
  except
    raise;
  end;
end;

//=============================================================================
//  実行時にSQLでパラメータを使用3
//  パラメータの名前を使い文字列バリアントで代入
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
begin
  if ADOConnection1.Connected = False then exit;

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日 BETWEEN :DATE1 AND :DATE2 ');

    ADOQuery1.Parameters.ParamByName('DATE1').Value := '1998/1/01';
    ADOQuery1.Parameters.ParamByName('DATE2').Value := '1998/1/31';

    ADOQuery1.Open;
  except
    raise;
  end;
end;

//=============================================================================
//  実行時にSQLでパラメータを使用4
//  パラメータ(バリアント)配列を使い日付を文字列で代入
//=============================================================================
procedure TForm1.Button4Click(Sender: TObject);
var
  DATE1 : String;
  DATE2 : String;
begin
  if ADOConnection1.Connected = False then exit;

  DATE1 := '1998/1/01';
  DATE2 := '1998/1/31';

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日>=:PARA1 AND 就労日<=:PARA2 ');

    ADOQuery1.Parameters.ParamValues['PARA1;PARA2'] := VarArrayOf([DATE1, DATE2]);

    ADOQuery1.Open;
  except
    raise;
  end;
end;

//=============================================================================
//  実行時にSQLでパラメータを使用5
//  パラメータ(バリアント)配列を使い日付を文字列で代入
//=============================================================================
procedure TForm1.Button5Click(Sender: TObject);
var
  DATE1 : TDateTime;
  DATE2 : TDateTime;
begin
  if ADOConnection1.Connected = False then exit;

  DATE1 := StrToDate('1998/1/01');
  DATE2 := StrToDate('1998/1/31');

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日 BETWEEN :PARA1 AND :PARA2 ');

    ADOQuery1.Parameters.ParamValues['PARA1;PARA2'] := VarArrayOf([DATE1, DATE2]);
    ADOQuery1.Open;
  except
    raise;
  end;
end;

//=============================================================================
//  実行時にSQLに直接日付を指定する場合
//  日付は#で囲む
//=============================================================================
procedure TForm1.Button6Click(Sender: TObject);
begin
  if ADOConnection1.Connected = False then exit;

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM TEST ');
    ADOQuery1.SQL.Add ('WHERE 就労日 BETWEEN #1998/01/01# AND #1998/01/31#');

    ADOQuery1.Open;
  except
    raise;
  end;
end;




04_部分一致検索の例


部分一致検索も書式が違います.以下のコードは,PO という文字があるレコードを検索します.


リスト4
部分一致検索の例
//=============================================================================
//  部分一致検索
//  ワイルドカードには%を使用する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if ADOConnection1.Connected = False then exit;

  ADOQuery1.Close;
  try
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add ('SELECT * FROM testtbl ');
    ADOQuery1.SQL.Add ('WHERE 住所 LIKE "%PO%" ' );

    ADOQuery1.Open;
  except
    raise;
  end;
end;




05_クロス集計 SQL の例


TADOQuery を使用する利点は,何と言ってもその SQL の機能の豊富さです.SQL 文の書式が違う場合もありますが,サブクエリが使用できたり,多くの関数が用意されています.インデックスさえ適切に設定すれば高速な処理が期待できます.

下のリストはクロス集計の例です.添付のサンプルで動作を確認できます.


図6
リスト 5 の結果
  • 月が列名
図7
リスト 6 の結果
  • 月が行方向

リスト5
クロス集計 SQL 文の例  1

TRANSFORM SUM(支払金額) 
SELECT 種別, SUM(支払金額) AS 支払額年計 
FROM TEST 
GROUP BY 種別 
PIVOT MONTH(就労日) 


リスト6
クロス集計 SQL 文の例  2

TRANSFORM SUM(支払金額) 
SELECT MONTH(就労日) AS 集計月,SUM(支払金額) AS 月支払合計 
FROM TEST 
GROUP BY MONTH(就労日) 
PIVOT 種別