Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2017年01月23日] [更新 2018年05月27日] Delphi サンプルプログラム集
   
566_Delphi 10.1 Berlin Starter で SQLite データベース
動作確認等 Windows 7 U64(SP2) + Delphi 10.1 Berlin Starter
FireDAC のサンプルは Delphi XE5(UP2) Pro
zeoslib-code-0-3961-branches-testing-7.2, SQLite 3.16.2
566_ZeosLib_SQLite_DelphiBerlin.zip [19,165 KB]  2017年02月25日版 (EXE 同梱)







Delphi 10.1 Berlin Starter で SQLite データベースに接続


SQLite は組み込み型データベース用のデータベース管理システムです.
組み込み型のデータベースは,作成したアプリの EXE に RDBMS (Relational DataBase Management System) の機能を組み込んだり,DLL 内の関数等を使用することにより RDBMS の機能を実装します.したがって,開発環境にも実行環境にも RDBMS をインストールする必要はありません.
SQLite は,C/S (クライアント/サーバ) アプリの構築には適していませんが,可搬型のデータベースアプリケーションが構築できます.

Delphi 10.1 Berlin Starter に ZeosLib をインストールすると,この SQLite の機能が利用できるようになります.本ページのサンプルは,この SQLite を使用した簡単な接続テストです.
データベースのシステムとして必要なのは sqlite3.dll という DLL だけです.

ZeosLib のインストール方法は,以下の JET データベースの記事で確認してください.JET データベースの記事には,ZeosLib におけるトランザクションと SQL 文のパラメータの設定方法のテストコードもあります.SQLite の詳しい情報は,以下のリンクあるいはネット上で検索してください.



[備考 1]
SQLiteは,Perl 5.8 以降,PHP 5 には標準で実装されています.SQLite が利用可能なレンタルサーバも多くあります.筆者が利用しているレンタルサーバも MySQL と SQLite が利用できます.普及しているデータベースの 1 つと言えます.


[備考 2]
FireDAC を使用して SQLite データベースに接続する記事がネット上にあります.Delphi XE Pro 版には FireDAC が標準では実装されていませんが,ZeosLib をインストールすれば,SQLLite データベースへの接続ができることをを確認しています.ZeosLib は Delphi 7 以降で使用可能です.
Delphi XE5 以降であれば Pro 版にも FireDAC が実装されています.





01_SQLite の入手


SQLite データベースを使用するために必要な sqlite3.dll は ZeosLib に添付されています.[lib] フォルダ内の [sqlite] [Wi32] 内にあります.

SQLite の最新版は以下のサイトのダウンロードのページから入手できます.
今回のテストでは sqlite-tools-win32-x86-3160200.zip をダウロードしました.win32 は 32 ビットの DLL です.win64 は 64 ビットの DLL です.Delphi 10.1 Berlin Starter では 64 ビットのアプリは開発できませんから,必要なのは 32 ビットの DLL ということになります.




図1
SQLite のダウンロード

下図は,ダウンロードした ZIP 書庫ファイルの内容です.使用するのは sqlite3.dll だけです.この DLL をシステム的にパスの通った場所におきます.今回は EXE ファイルと同じフォルダ内に置いてテストしています.


図2
ZIP 書庫の内容
  • 使用するのは DLL だけ




02_ZeosLib を使用して SQLite データベースに接続


ZeosLib を使用して,SQLite のデータベースに接続し,表のデータを表示するサンプルです.
日本語の表名や項目名 (フィールド名) は,[] あるいは " (ダブルクォーテーション) で括らないと例外が発生して正常に動作しません.これも含めて,エラー処理は一切していません.

SQLite のデータベースは,JET エンジンのデータベースと同じで,1 つのファイルに複数の表 (テーブル) を格納する方式です.



[備考]
データベースの操作には主に SQL を使用します.SQL に関する参考書は多く出版されています.ネット上にも多くの関係記事があります.


図3
設計時画面
  • TDBGrid は
    [Data Controls] に,
    TDataSource は
    [Data Access] にある
図4
Button1 クリックの結果
図5
Button2 クリックの結果

リスト1
ZeosLib を使用して SQLite データベースに接続
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  ZAbstractConnection, ZConnection, StdCtrls, Grids, DBGrids;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    Button1: TButton;
    DataSource1: TDataSource;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //sqlite3.dllが存在する場所の指定
  ZConnection1.LibraryLocation := ExpandFileName('..\sqlite3.dll');

  //TDataSource,TDBGridの設定
  DataSource1.DataSet := ZQuery1;
  DBGrid1.DataSource  := DataSource1;
end;

//=============================================================================
//  フォームを閉じる時の処理
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ZQuery1.Close;
  ZConnection1.Disconnect;
end;

//=============================================================================
//  ZeosLibを使用してSQLiteのデータベースに接続
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  //念のため接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\TestSQLite.db3');
  //データベースへ接続
  ZConnection1.Connect;

  //TZQueryの設定
  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;
  ZQuery1.SQL.Clear;
  ZQuery1.SQL.Add('select * from Syokuhin');

  //クエリの実行
  ZQuery1.Open;
end;

//=============================================================================
//  ZeosLibを使用してSQLiteのデータベースに接続
//  日本語は[]または"(ダブルクォーテーション)で括る
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  //念のため接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\TestSQLite.db3');
  //データベースへ接続
  ZConnection1.Connect;

  //TZQueryの設定
  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;
  ZQuery1.SQL.Clear;
  ZQuery1.SQL.Add('select * from Syokuhin where "食品群" like "野菜%"');

  //クエリの実行
  ZQuery1.Open;
end;

end.




03_ZeosLib を使用した SQLite データベースと表の新規作成


SQLite のデータベースを新規に作成するテストプログラムです.

SQLite が扱う文字列は,長さ制限がない TEXT というデータ型です.本サシンプルでは,文字列型の項目を VARCHAR() で定義しています.() 内は文字数です.VARCHAR 型で定義しないと,TDBGrid 等に文字列として正常に表示できません.
VARCHAR() で文字列の長さを設定すると,TDBGrid 等のデータベース用の入力コントロールからは,その文字数を超えての入力ができなくなります.



[備考]
VARCHAR() による文字数の設定は,TDBGrid 等のデータベース用コントロールでの入力制限です.
この設定をしても,該当フィールドには,その文字数以上の文字列を代入できます.代入した文字列を TDBGrid 等のコントロールに表示すると,その全てが表示されます.


図6
設計時の画面
図7
新規に作成したデータベースのデータを表示
  • Button1 クリックでデータベースを新規に作成
  • Button2 クリックで表示
  • もし,Button2 を先にクリックしてしまったら,AddressBook.db3 を削除してから再度実行
図8
データを追加入力中
  • ID は入力しなくても自動で入力される

リスト2
ZeosLib を使用した SQLite データベースと表の新規作成
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  ZAbstractConnection, ZConnection, StdCtrls, Grids, DBGrids;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    Button1: TButton;
    DataSource1: TDataSource;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //sqlite3.dllが存在する場所の指定
  ZConnection1.LibraryLocation := ExpandFileName('..\sqlite3.dll');

  //TDataSource,TDBGridの設定
  DataSource1.DataSet := ZQuery1;
  DBGrid1.DataSource  := DataSource1;
end;

//=============================================================================
//  フォームを閉じる時の処理
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ZQuery1.Close;
  ZConnection1.Disconnect;
end;

//=============================================================================
//  ZeosLibを使用してSQLiteのデータベースを作成
//  ZConnection1.Databaseで指定したデータベース名がなければ自動作成
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LDataBaseName : string;
begin
  LDataBaseName := ExpandFileName('..\AddressBook.db3');
  if FileExists(LDataBaseName) then exit;

  //念のため接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\AddressBook.db3');
  ZConnection1.Connect;
  ZConnection1.Disconnect;

  ZQuery1.Close;
  ZQuery1.Connection := ZConnection1;

  //表を作成
  ZQuery1.SQL.Text := 'CREATE TABLE AddressTBL'
                    + ' ('
                    + ' ID INTEGER PRIMARY KEY,'
                    + ' "氏名" VARCHAR(30),'
                    + ' "生年月日" DATETIME,'
                    + ' "住所" VARCHAR(50)'
                    + ')';
  ZQuery1.ExecSQL;

  //インデックスを作成
  ZQuery1.SQL.Text := 'CREATE INDEX IDNO ON AddressTBL(ID)';
  ZQuery1.ExecSQL;

  //コードでデータを作成
  //数値以外は"(ダブルクォーテーション)で括る
  ZQuery1.SQL.Text := 'INSERT INTO AddressTBL'
                    + '('
                    + '"氏名", "生年月日", "住所"'
                    + ')'
                    + ' VALUES ('
                    + '"日本 太郎", "2005/10/25", "東京都京都市大町 2-510"'
                    + ');';
  ZQuery1.ExecSQL;
end;

//=============================================================================
//  ZeosLibを使用してSQLiteのデータベースに接続
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  //念のため接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\AddressBook.db3');
  //データベースへ接続
  ZConnection1.Connect;

  //TZQueryの設定
  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;
  ZQuery1.SQL.Clear;
  ZQuery1.SQL.Add('select * from AddressTBL');

  //クエリの実行
  ZQuery1.Open;
  //日付型は書式を設定してみる
  (ZQuery1.FieldByName('生年月日') as TDateTimeField).DisplayFormat := 'ggee年mm月dd日';
end;

end.


設定する文字列に ' (シングルクォーテーション,シングルクォート) が含まれる場合は,以下のように ' を 2 つ続けて書きます.そうすると 1 つの ' として認識しくれます.
コード中の LAddress は string 型の変数です.



図9
' (シングルクォーテーション) を文字列に含める例
  • コードで設定するときは ' を 2 つ続けて書く

  //コードでデータを作成
  //数値以外は"(ダブルクォーテーション)で括る
  LAddress := QuotedStr('東京''都京都市大町 2-510');
  ZQuery1.SQL.Text := 'INSERT INTO AddressTBL'
                    + '('
                    + '"氏名", "生年月日", "住所"'
                    + ')'
                    + ' VALUES ('
                    + '"日本 太郎", "2005/10/25",' + LAddress
                    + ');';


TEdit で入力した値を使用する場合は,' を 2 つ続けて入力する必要はありません.そのままで認識してくれます.以下はその例です.
このシングルクォーテーションの扱い方は,Delphi の文字列でシングルクォーテーションを処理する時の一般的な方法です.



図10
' (シングルクォーテーション) を文字列に含める例
  • TEdit 等に入力した ' はそのままで認識してくれる

  //コードでデータを作成
  //数値以外は"(ダブルクォーテーション)で括る
  LAddress := QuotedStr(Edit1.Text);
  ZQuery1.SQL.Text := 'INSERT INTO AddressTBL'
                    + '('
                    + '"氏名", "生年月日", "住所"'
                    + ')'
                    + ' VALUES ('
                    + '"日本 太郎", "2005/10/25",' + LAddress
                    + ');';


" (ダブルクォーテーション,ダブルクォート ) は,SQL に文字列として認識させるためのダブルクォーテーションを,次のように QuotedStr を使用して追加すれば,文字列の中のダブルクォーテーションをそのまま認識して処理してくれます.



図11
文字列に " (ダブルクォーテーション) がある例

  //コードでデータを作成
  //数値以外は"(ダブルクォーテーション)で括る
  LAddress := QuotedStr('東京"都京都市大町 2-510');
  ZQuery1.SQL.Text := 'INSERT INTO AddressTBL'
                    + '('
                    + '"氏名", "生年月日", "住所"'
                    + ')'
                    + ' VALUES ('
                    + '"日本 太郎", "2005/10/25",' + LAddress
                    + ');';


QuotedStr を使用しない場合は,次のように " (ダブルクォーテーション) を 2 つ続けて書かないと 実行時に例外が発生します.



  //コードでデータを作成
  //数値以外は"(ダブルクォーテーション)で括る
  LAddress := '"東京""都京都市大町 2-510"';
  ZQuery1.SQL.Text := 'INSERT INTO AddressTBL'
                    + '('
                    + '"氏名", "生年月日", "住所"'
                    + ')'
                    + ' VALUES ('
                    + '"日本 太郎", "2005/10/25",' + LAddress
                    + ');';




04_別の SQLite データベースの表からデータをインポート


データベースの別のテーブル (表) のデータを取り込んたり,あるいは別の表にデータを挿入する操作の参考コードです.ただし,本項ではインポート,つまり取り込み操作だけです.同じ様な方法を使えばエクスポートもできます.

別のテーブルのデータを操作を行うには,各々の表を開いて操作することで可能です.
SQLite には別の SQLite のデータベースへのアタッチという機能があります.本サンプルはこ機能をテストしたものです.両方の表の項目数と項目名が一致している場合に使用できるコードです.

テストに使用した表にはプライマリキーが設定されています.このプライマリキーは自動的に数値が設定されるようになっています.プライマリキーの値は重複して登録できません.したがって,プライマリキーの値が同じレコードはインポートできません.

本サンプルではトランザクション分離レベルの値をデフォルトの tiNone にしています.他の値にするとデタッチの時に例外が発生します.また,再度アタッチする時も例外が発生します.



図12
設計時の画面
図13
元の表のデータ
  • ここに下図のデータをインポート (挿入) する
図14
インポートするデータ
  • このデータを上の図の表に追加挿入する

下図が実行結果です.別の表にあるプライマリキーの値が同じである [山田 太郎] と [山田 花子] のレコードが挿入されていないことが確認できます.新規に作成した表にデータをセットする場合は,全てのデータがインポートされることになります.



図15
インポートの結果
  • [山田 太郎] と [山田 花子] のデータは挿入されていない

リスト3
別の SQLite データベースの表からデータをインポート
プライマリキーが同じ値のレコードはインポートしないコード
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  ZAbstractConnection, ZConnection, StdCtrls, Grids, DBGrids;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    Button1: TButton;
    DataSource1: TDataSource;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    Button2: TButton;
    ZConnection2: TZConnection;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    FDBName    : string;
    FTableName : string;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
 ZDbcIntfs;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //sqlite3.dllが存在する場所の指定
  ZConnection1.LibraryLocation := ExpandFileName('..\..\sqlite3.dll');
  ZConnection2.LibraryLocation := ExpandFileName('..\..\sqlite3.dll');

  //TDataSource,TDBGridの設定
  DataSource1.DataSet := ZQuery1;
  DBGrid1.DataSource  := DataSource1;

  FDBName    := ExpandFileName('..\..\AddressBook_A.db3');
  FTableName := 'AddressTBL';
end;

//=============================================================================
//  フォームを閉じる時の処理
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection2.Disconnect;
end;

//=============================================================================
//  データベースの指定の表のデータをTDBGridに表示
//  インポートした結果の確認用
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  //接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;
  ZConnection1.Protocol    := 'sqlite-3';
  ZConnection1.Database    := FDBName;
  //データベースへ接続
  ZConnection1.Connect;

  //TZQueryの設定
  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;
  ZQuery1.SQL.Clear;
  ZQuery1.SQL.Add('select * from ' + FTableName);

  //クエリの実行
  ZQuery1.Open;
  //日付型は書式を設定してみる
  (ZQuery1.FieldByName('生年月日') as TDateTimeField).DisplayFormat := 'ggee年mm月dd日';
end;

//=============================================================================
//  別のSQLIteのデータベースの表のデータをインポート
//  ATTACH DATABASEを使用してSELECT文で全ての項目の値をインポートする例
//
//  グローバル変数の値は以下通り
//  FDBName    := ExpandFileName('..\..\AddressBook_A.db3');
//  FTableName := 'AddressTBL';
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LInportDBName  : string;
  LInportTblName : string;
  LSQLText       : string;
begin
  //データを挿入するデータベースとその表名の設定
  ZConnection2.Disconnect;
  ZConnection2.LoginPrompt := False;
  ZConnection2.Protocol    := 'sqlite-3';
  ZConnection2.Database    := FDBName;

  ZConnection2.Connect;

  //インポートするデータがあるデータベースの設定をしてアタッチする
  //データベースのエイリアス(別名)が設定できる
  LInportDBName  := AnsiQuotedStr(ExpandFileName('..\..\AddressBook_B.db3'), '"');
  LInportTblName := 'AddressTBL';

  ZConnection2.ExecuteDirect('ATTACH DATABASE ' + LInportDBName + ' AS LInportDB');

  //トランザクション開始
  ZConnection2.TransactIsolationLevel := tiNone;
  ZConnection2.StartTransaction;
  try
    //実行するインサート用のSQL文
    //IGNOREを指定しているのでプライマリキーの値が重複するレコードは挿入しない
    //IGNOREを指定しないと,重複するプライマリキーのレコードでエラーが発生する
    LSQLText := 'INSERT OR IGNORE INTO ' + FTableName + ' '
              + 'SELECT * FROM LInportDB.' + LInportTblName;

    ZConnection2.ExecuteDirect(LSQLText);

    //コミット
    ZConnection2.Commit;
  except
    ZConnection2.Rollback;
    MessageBox(Handle, '挿入に失敗しました', '失敗', MB_ICONINFORMATION);
  end;

  //デタッチ
  ZConnection2.ExecuteDirect('DETACH DATABASE LInportDB;');
  ZConnection2.Disconnect;
end;

end.


プライマリキーの値が同じレコードもインポートするには,例えば以下のように,インポートする項目を指定します.
インポートする項目を個別に指定するこの方法は,両方の表の項目数と項目名が一致しなくてもインポートが可能です.



図16
インポートの結果
  • [山田 太郎] と [山田 花子] のデータも挿入されている
  • 上のサンプルのテスト前にバックアップしておいた AddressBook_A.db3 を使用

リスト4
別の SQLite データベースの表からデータをインポート
プライマリキーの値をインポートする項目から除外するコード
//=============================================================================
//  別のSQLIteのデータベースの表のデータをインポート
//  ATTACH DATABASEを使用してSELECT文でインポートする項目を指定する例
//
//  グローバル変数の値は以下通り
//  FDBName    := ExpandFileName('..\..\AddressBook_A.db3');
//  FTableName := 'AddressTBL';
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LInportDBName  : string;
  LInportTblName : string;
  LSQLText       : string;
begin
  //データを挿入するデータベースとその表名の設定
  ZConnection2.Disconnect;
  ZConnection2.LoginPrompt := False;

  ZConnection2.Protocol := 'sqlite-3';
  ZConnection2.Database := FDBName;
  //データベースへ接続
  ZConnection2.Connect;

  //インポートするデータがあるデータベースの設定をしてアタッチする
  //データベースのエイリアス(別名)が設定できる
  LInportDBName  := AnsiQuotedStr(ExpandFileName('..\..\AddressBook_B.db3'), '"');
  LInportTblName := 'AddressTBL';
  ZConnection2.ExecuteDirect('ATTACH DATABASE ' + LInportDBName + ' AS LInportDB');

  //トランザクション開始
  ZConnection2.TransactIsolationLevel := tiNone;
  ZConnection2.StartTransaction;
  try
    //実行するインサート用のSQL文
    //挿入する項目にプライマリキーの値を含めてないので全て挿入される
    LSQLText := 'INSERT INTO ' + FTableName
              + '("氏名", "生年月日", "住所") '
              + 'SELECT "氏名", "生年月日", "住所" FROM LInportDB.' + LInportTblName;

    ZConnection2.ExecuteDirect(LSQLText);

    //コミット
    ZConnection2.Commit;
  except
    ZConnection2.Rollback;
    MessageBox(Handle, '挿入に失敗しました', '失敗', MB_ICONINFORMATION);
  end;

  //デタッチ
  ZConnection2.ExecuteDirect('DETACH DATABASE LInportDB');
  ZConnection2.Disconnect;
end;


次のサンプルもアタッチを使用しないで,レコード単位でインポートする例です.
値のセットには SQL の VALUES を使用して,インポートする項目を個別に指定していますから,両方の表の項目数と項目名が一致しなくてもインポートできます.

項目値は SQL のパラメータで設定するようにしています.SQL 文でも計算等の処理が可能ですが,パラメータで設定すると,いろいろな処理の結果をパラメータに渡すことができます.レコード単位での処理ですから,条件によってはインポートしないレコードを決めることもできます.


リスト5
別のデータベースの表からデータをインポート
レコード単位でインポートする例
//=============================================================================
//  別のSQLIteのデータベースの表のデータをインポート
//  ATTACH DATABASEを使用しない汎用的な方法
//
//  項目のデータをパラメータで,VALUESで値として設定
//  任意の項目値だけのインポートも可能
//  両方の表の項目数と項目名が一致していなくてもインポート可能
// インサートする表データをのレコード単位で処理する
//
//  グローバル変数の値は以下通り
//  FDBName    := ExpandFileName('..\..\AddressBook_A.db3');
//  FTableName := 'AddressTBL';
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LInportDBName  : string;
  LInportTblName : string;
  LSQLText       : string;
begin
  //インポートする側のデータベース(メイン)
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := FDBName;
  ZConnection1.Properties.Values['PrepareSQL'] := 'True';
  //データベースへ接続
  ZConnection1.Connect;
  ZQuery1.Connection := ZConnection1;

  //インポートするデータがあるデータベースの設定と接続
  LInportDBName  := ExpandFileName('..\..\AddressBook_B.db3');
  LInportTblName := 'AddressTBL';

  ZConnection2.Disconnect;
  ZConnection2.LoginPrompt := False;
  ZConnection2.Protocol    := 'sqlite-3';
  ZConnection2.Database    := LInportDBName;

  ZQuery2.Connection := ZConnection2;
  ZQuery2.Close;
  ZQuery2.SQL.Text := 'SELECT * FROM ' + LInportTblName;
  ZQuery2.Open;


  //トランザクション開始
  ZConnection1.TransactIsolationLevel := tiRepeatableRead;
  ZConnection1.StartTransaction;
  try
    //実行するインサート用のSQL文
    //挿入する項目にプライマリキーの値を含めていないので必ず挿入可能
    //代入しない項目の値としてnullが使用可能
    LSQLText := 'INSERT INTO ' + FTableName + ' '
              + '("氏名", "生年月日", "住所") '
              + 'VALUES (:Val1, :Val2, :Val3)';

    //パラメータのチェックありにする
    ZQuery1.ParamCheck := True;

    ZQuery2.First;
    while not ZQuery2.Eof do begin
      ZQuery1.SQL.Text := LSQLText;

      //クエリのパラメータの設定
      ZQuery1.ParamByName('Val1').AsString :=
                                  ZQuery2.FieldByName('氏名').AsString;
      ZQuery1.ParamByName('Val2').AsDateTime :=
                                  ZQuery2.FieldByName('生年月日').AsDateTime;
      ZQuery1.ParamByName('Val3').AsString :=
                                  ZQuery2.FieldByName('住所').AsString;

      //更新クエリの実行
      ZQuery1.ExecSQL;

      //次のレコード
      ZQuery2.Next;
    end;

    //コミット
    ZConnection1.Commit;
  except
    ZConnection1.Rollback;
    MessageBox(Handle, '挿入に失敗しました', '失敗', MB_ICONINFORMATION);
  end;

  ZQuery1.Close;
  ZQuery2.Close;
  ZConnection1.Disconnect;
  ZConnection2.Disconnect;
end;




05_SQLite データベースに CSV ファイルからデータをインポート


前項の最後のサンプルは,別のデータベースの表からデータをインポートする汎用的なコードとして応用できます.本サンプルは,CSV ファイルからデータをインポートします.
本サンプルも,前項の最後のサンプルと同じく,VALUES で指定した項目にパラメータで値を設定してレコード単位でインポートします.この時,プライマリキーを除外していますから,プライマリキーの値が同じであってもデータをインポートします.

ZeosLib はいくつかの種類のデータベースへの接続ができます.また,ADO の機能も利用できますから,テキストファイル,エクセル (Excel) のシート,あるいは Paradox, dBASE や Access のデータベースである JET データベースにも接続できます.したがって,それらからデータをインポートしたり,エクスポートできることになります.



[備考 1]
重複するレコードは,プライマリキーの値に対する扱い等,条件の指定が必要ですが,基本的には SQL の DELETE 文で削除できます..


[備考 2]
INSERT INTO 文内の SELECT 文では,異種の,異なるデータベースエンジンのデータベースの表を操作の対象にはできません.異種のデータベースの表からインポートする場合は,レコード単位での処理になります.



図17
設計時の画面
図18
読み込むデータ
  • このデータをインポートする
  • このテキストファイルの文字のコードページは Shift-JIS
  • SQLite の日付の形式は yyyy-mm-dd なので,その形式にしておいた方がよい
図19
インポートの結果
  • 前項のサンプルのテスト前にバックアップしておいた
    AddressBook_A.db3
    を使用
図20
更にインポートした結果
  • 同じデータが挿入される

リスト6
SQLite データベースに CSV ファイルからデータをインポート
//=============================================================================
//  異種データベースからのインポートの汎用的な方法例
//  CSVファイルからテキストデータをインポート
//
//  項目のデータをVALUESで値として設定
//  データをのレコード単位で処理する
//
//  グローバル変数の値は以下通り
//  FDBName    := ExpandFileName('..\AddressBook_A.db3');
//  FTableName := 'AddressTBL';
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LTextDBName     : string;
  LTextTblName    : string;
  LTextConnectStr : string;
  LSQLText        : string;
begin
  //インポートする側のデータベース(メイン)
  //SQLの実行以外はButton1クリックのコードと同じ
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;
  ZConnection1.Properties.Values['PrepareSQL'] := 'True';

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := FDBName;
  //データベースへ接続
  ZConnection1.Connect;
  ZQuery1.Connection := ZConnection1;


  //---------------------------------------------------------------------------
  //  インポートするデータがあるデータベースの設定開始
  //  テキストファイル,エクセルのシート,Paradox,dBASE,JET(Accessのデータベース)
  //  等はadoの機能を使用すると接続できる
  //---------------------------------------------------------------------------
  LTextDBName  := AnsiQuotedStr(ExpandFileName('..\'), '"');
  LTextTblName := 'CsvText.csv';
  //表名の.は#に置換える
  LTextTblName := StringReplace(LTextTblName, '.', '#', [rfReplaceAll]);

  ZQuery2.Close;
  ZConnection2.Disconnect;
  ZConnection2.ReadOnly    := True;
  ZConnection2.LoginPrompt := False;

  //接続文字列の設定
  //1行目もデータなのでHDR=NOを指定
  LTextConnectStr := 'Provider=Microsoft.Jet.OLEDB.4.0'
                   + ';Data Source=' + LTextDBName
                   + ';Extended Properties="Text;HDR=NO;"'

                   + ';Persist Security Info=False';

  ZConnection2.Database := LTextConnectStr;
  ZConnection2.Protocol := 'ado';
  //データベースへ接続
  ZConnection2.Connect;
  ZQuery2.Connection := ZConnection2;

  ZQuery2.Close;
  ZQuery2.SQL.Text := 'SELECT * FROM ' + LTextTblName + '';
  ZQuery2.Open;
  //---------------------------------------------------------------------------
  //  インポートするデータがあるデータベースへの接続完了
  //  データセットがTZQueryに格納される
  //---------------------------------------------------------------------------


  //トランザクション開始
  ZConnection1.TransactIsolationLevel := tiRepeatableRead;
  ZConnection1.StartTransaction;
  try
    //実行するインサート用のSQL文
    //挿入する項目にプライマリキーの値を含めていないので必ず挿入可能
    //代入しない項目の値としてnullが使用可能
    LSQLText := 'INSERT INTO ' + FTableName + ' '
              + '("氏名", "生年月日", "住所") '
              + 'VALUES (:Val1, :Val2, :Val3)';

    //パラメータのチェックありにする
    ZQuery1.ParamCheck := True;

    ZQuery2.First;
    while not ZQuery2.Eof do begin
      ZQuery1.SQL.Text := LSQLText;

      //クエリのパラメータの設定
      //項目名がないテキストファイルでは自動的にF1,F2,... という項目名になる
      ZQuery1.ParamByName('Val1').AsString   := ZQuery2.FieldByName('F2').AsString;
      ZQuery1.ParamByName('Val2').AsDateTime := ZQuery2.FieldByName('F3').AsDateTime;
      ZQuery1.ParamByName('Val3').AsString   := ZQuery2.FieldByName('F4').AsString;

      //更新クエリの実行
      ZQuery1.ExecSQL;

      ZQuery2.Next;
    end;

    //コミット
    ZConnection1.Commit;
  except
    ZConnection1.Rollback;
    MessageBox(Handle, '挿入に失敗しました', '失敗', MB_ICONINFORMATION);
  end;

  ZQuery1.Close;
  ZQuery2.Close;
  ZConnection1.Disconnect;
  ZConnection2.Disconnect;
end;




06_SQLite の GUI 操作ツール TkSQLite


データベースの GUI 操作ツールを利用すれば,データベースの新規作成や表定義の編集,データの操作等が GUI で行えて便利です.SQLite のデータベースを GUI で操作できるツールはいくつかありますが,その中の TkSQLite というツールの紹介です.

以下のサイトで [ダウンロード] をクリックすると,ダウンロードファイルの一覧があります.下の方が新しいバージョンになっています.
今回は tksqlite-0.5.13-win32-bin.zip をダウンロードしました.これは 32 ビット版です.win64 となっているのが 64 ビットの EXE です.64 ビットの Windows ではどちらでも利用可能です.ダウンロードした ZIP 書庫に格納されているのは tksqlite.exe だけです.



[備考]
TkSQLite.exe は日本語名のフォルダの階層下からは起動できません.データベースのファイルは日本語名のフォルダの階層下にあっても開くことができます.


図21
TkSQLite のダウンロードファイル一覧

TkSQLite の設定関係のファイルは以下のフォルダにあります.アンインストールは TkSQLite.exe を削除するだけですが,このフォルダも削除します.


%APPDATA%/tksqlite/


本ページの最初のサンプルのデータは,カンマ区切りのテキストデータを,この TkSQLite で読み込んで作成しています.

TkSQLite で表の文字列の項目のデータ型を設定する時は注意が必要です.
文字列のデータ型は VARCHAR 型にします.TEXT または CHAR 型にすると,Delphi では TMemo 型のテキストとして認識してしまうため, TDBGrid で表示した時に (WIDEMEMO) と表示されてしまいます.データ型のリストには VARCHAR 型がないので,キーボードからタイプして設定します.

項目の設定画面は,テーブル名のポップアップから [テーブルスキーマの変更] で表示します.表示ししたダイアログで,編集する項目をダブルクリックすると [カラム変更] ができます.



図22
データベースの表を表示
  • メニュー類は自動で日本語表示となる
図23
文字列のデータ型は VARCHAR 型とする
  • 文字列の長さは () で指定
  • () 内は文字数




07_SQLite の GUI 操作ツール PupSQLite


PupSQLite は日本製です.上の記事で紹介している TkSQLite よりも機能が豊富です.詳しい HTML ヘルプが添付されています.
項目は,テーブル名のポップアップメニューから [カラムの編集] のダイアログで設定できます.文字列の項目は,データ型を TEXT にして文字数を設定します.

PopSQLite は以下のリンクからダウンロードできます.



図24
カラムの編集画面
  • 文字列の項目は,データ型を TEXT にして文字数を設定する
図25
添付の HTML ヘルプ




08_SQLite の GUI 操作ツール SQLite Expert Personal


表示は英語ですが,これも機能が豊富です.以下のリンクからダウンロードできます.
画面のデザインが Style のリストで変更できます.Personal 版はフリー版ですが,更に機能が充実した Professional 版があります.SQLite Expert は Delphi で開発されています.
データ型のリストに VARCHAR があります.



図26
本ページの添付のデータベースのデータを表示
図27
カラムの編集画面
  • [Modify] またはダブルクリックで選択項目の設定ダイアログを表示




09_FireMonkey で ZeosLib を使用した SQLite データベース接続


ZeosLib は FireMonkey の環境でも利用できます.その確認テストです.既に ZeosLib がインストール済みであれば FireMonkey でもすぐに使用できます.
下図は [ファイル] [新規作成] から [マルチデバイスアプリケーション Delphi] を選択して,[空のアプリケーション] を作成した設計時の画面です.



図28
設計時に配置したコンポーネント
  • 以下のコンポを配置.[] 内はコンポーネントパレットのタブ名

    TButton [Standard]
    TZConnection [Zeos Access]
    TZQuery [Zeos Access]
    TStringGrid [Grids]
    TDataSource [Data Access]
    TBindSourceDB [LiveBindings]
    TBindingsList [LiveBindings Misc]

TBindingsList コンポーネントは,バインディングコンポーネントを作成するためのものです.

FireMonkey には,VCL のコンポーネントパレットの [Data Controls] タブにある TDBGrid, TDBEdit 等のデータベース表示用のコントロールはありません.バインディングコンポーネントを生成し,データベース関係のコンポーネントとバインドすることにより,データがリンクされます.
つまり,バインディングコンポーネントを使用すると,通常の表示用コントロールをデータベース対応の表示用コントロールにすることができます.

下図は,TStringGrid にデータを表示するようにするための設定手順です.



図29
バイン6ィングコンポーネント編集
  • TBindingsList コンポ上でマウスの右ボタンクリック
  • 新規なので [LiveBinding コンポーネントの新規作成] でもよい
図30
バインディングコンポーネント追加
  • [バインディングの新規作成] をクリックして
    [TLinkGridToDataSource]
    を選択して [OK] で閉じる
  • 今回作成するのはこれだけ
図31
追加したバインディングコンポーネントのプロパティを設定
  • 設定対象のバインドコンポーネントを選択して
  • DataSource の値を
    BindSourceDB1 に
  • GridControl の値を
    StringGrid1 にする

下図が実行結果です.本ページの最初のサンプルと同じデータベースに接続しています.Button1 クリックのコードは,最初のサンプルと全く同じです.
TStringGrid は文字列を表示します.したがって,数値データも左寄せで表示されています.



図32
実行結果
  • カラム幅は手動で変更している

リスト7
FireMonkey で ZeosLib を使用した SQLite データベース接続
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Rtti,
  FMX.Grid.Style, Data.DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  ZAbstractConnection, ZConnection, Data.Bind.Components, Data.Bind.DBScope,
  FMX.ScrollBox, FMX.Grid, FMX.Controls.Presentation, FMX.StdCtrls,
  Data.Bind.EngExt, Fmx.Bind.DBEngExt, System.Bindings.Outputs,
  Fmx.Bind.Editors, Data.Bind.DBLinks, Fmx.Bind.DBLinks, Fmx.Bind.Grid,
  Data.Bind.Grid;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    DataSource1: TDataSource;
    BindSourceDB1: TBindSourceDB;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    BindingsList1: TBindingsList;
    LinkGridToDataSource1: TLinkGridToDataSource;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

//============================================================================
//  フォーム生成時の処理
//============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //sqlite3.dllが存在する場所の指定
  ZConnection1.LibraryLocation := ExpandFileName('..\sqlite3.dll');

  //TDataSource,TBindSourceDBの設定
  DataSource1.DataSet      := ZQuery1;
  BindSourceDB1.DataSource := DataSource1;
end;

//=============================================================================
//  フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
  ZQuery1.Close;
  ZConnection1.Disconnect;
end;

//============================================================================
//  ZeosLibを使用してSQLiteのデータベースに接続
//============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  //念のため接続を切断してから設定
  ZQuery1.Close;
  ZConnection1.Disconnect;
  ZConnection1.LoginPrompt := False;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\TestSQLite.db3');
  //データベースへ接続
  ZConnection1.Connect;

  //TZQueryの設定
  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;
  ZQuery1.SQL.Clear;
  ZQuery1.SQL.Add('select * from Syokuhin');

  //クエリの実行
  ZQuery1.Open;
end;

end.


バインディングコンポーネントは,下のコードで示すように実行時に生成することもできます.ただし,必要なユニット名を uses 部に追加しなければなりません.この必要なユニットを調べるのは結構面倒です.今回は上のサンプルの uses 部のコードをそのままコピーして使用しました.

バインディングコンポーネントの設定は,設計時に IDE から行う方が便利です.



リスト8
バインディングコンポーネントを実行時に生成する例
//============================================================================
//  フォーム生成時の処理
//  バインディングコンポーネントを実行時に生成する場合
//  usesに複数のユニット名を追加する必要がある
//
//  FBindingList  : TBindingsList;
//  FLinkGridToDS : TLinkGridToDataSource;
/============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //TDataSource,TBindSourceDBの設定
  DataSource1.DataSet      := ZQuery1;
  BindSourceDB1.DataSource := DataSource1;

  //バインディングリストの生成
  FBindingList := TBindingsList.Create(Self);

  //バインディングリストにTLinkGridToDataSourceを追加
  FLinkGridToDS := TLinkGridToDataSource.Create(FBindingList);

  //追加したTLinkGridToDataSourceのプロパティを設定
  FLinkGridToDS.DataSource  := BindSourceDB1;
  FLinkGridToDS.GridControl := StringGrid1;
end;




10_ZeosLib使用時におけるSQLiteのバージョン取得


ZeosLib を使用して SQLite のデータベースに接続している時,使用中の SQLite のバージョンを取得するには,SELECT 文で sqlite_version() 関数を実行します.



図33
SQLite のバージョンを取得

リスト9
ZeosLib使用時におけるSQLiteのバージョン取得
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  ZAbstractConnection, ZConnection, StdCtrls, Grids, DBGrids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  ZeosLib使用時におけるSQLiteのバージョン取得
//  select文でsqlite_version()関数を実行
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LVersionText : string;
begin
  ZConnection1.LibraryLocation := ExpandFileName('..\sqlite3.dll');

  ZQuery1.Close;
  ZConnection1.Disconnect;

  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\AddressBook_A.db3');

  ZQuery1.Connection := ZConnection1;
  ZQuery1.Close;

  ZQuery1.SQL.Text := 'select sqlite_version() vrsn';
  ZQuery1.Open;
  if ZQuery1.Eof = False then begin
    LVersionText := ZQuery1.FieldByName('vrsn').AsString;
  end else begin
    LVersionText :='不明';
  end;
  ZQuery1.Close;
  ZConnection1.Disconnect;

  MessageBox(Handle, PChar(LVersionText), 'バージョン', MB_ICONINFORMATION);
end;

end.


実行中の SQLite のバージョンは,以下のように TZConnection のプロパティからも取得できます.



procedure TForm1.Button1Click(Sender: TObject);
var
  LVersionText : string;
begin
  ZConnection1.LibraryLocation := ExpandFileName('..\sqlite3.dll');
  ZConnection1.Protocol := 'sqlite-3';
  ZConnection1.Database := ExpandFileName('..\AddressBook_A.db3');

  ZConnection1.Connect;

  //文字列で取得
  LVersionText :=  ZConnection1.ServerVersionStr + sLineBreak
                +  ZConnection1.ClientVersionStr;

  //整数値で取得
  LVersionText :=  IntToStr(ZConnection1.ServerVersion) + sLineBreak
                +  IntToStr(ZConnection1.ClientVersion);
end;




11_FireDAC を使用した SQLite データベースへの接続


本ページの最初の方で,Delphi XE5 以降であれば Pro 版でも FireDAC が使用でき,SQLite データベースに接続てきることを書きました.
以下は実際に,FireDAC を使用して SQLite のデータベースに接続するサンプルです.SQLite のデフォルトのコードページは BOM なしの UTF-8 です.したがって,StringFormat を Unicode にしておきます.そうしないと日本語が正常に表示できません.

FireDAC には SQLite の機能が組み込まれています.sqlite3.dll は必要ありません.
Delphi 10.1 Berlin Starter では FireDAC は利用できません.



図34
設計時の画面
図35
SQLite データベースに接続
  • 添付の AddressBook_B.db3 に接続してデータを表示
図36
SQLite のバージョンを取得

リスト10
FireDAC を使用した SQLite データベースへの接続
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf,
  FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
  FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt,
  FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys,
  FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLite, Data.DB, FireDAC.Comp.Client,
  FireDAC.Comp.DataSet, Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids,
  FireDAC.VCLUI.Wait, FireDAC.Comp.UI;

type
  TForm1 = class(TForm)
    FDQuery1: TFDQuery;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Button1: TButton;
    Button2: TButton;
    FDConnection1: TFDConnection;
    FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    FDQuery2: TFDQuery;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
    FDBFileName : string;
    FTableName  : string;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.DataSet := FDQuery1;
  DBGrid1.DataSource  := DataSource1;

  FDBFileName := ExpandFileName('..\AddressBook_B.db3');
  FTableName  := 'AddressTBL';

  FDConnection1.Connected := False;

  FDConnection1.Params.Clear;
  FDConnection1.Params.Add('DriverID=SQLite');
  FDConnection1.Params.Add('Database=' + FDBFileName);
  FDConnection1.Params.Add('StringFormat= Unicode');
end;

//=============================================================================
//  フォームを閉じる時の処理
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FDQuery1.Close;
  FDQuery2.Close;
  FDConnection1.Connected := False;
end;

//=============================================================================
//  FireDACを使用したSQLiteデータベースへの接続
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  FDQuery1.Close;
  FDQuery1.Connection := FDConnection1;

  FDQuery1.SQL.Clear;
  FDQuery1.SQL.Add('select * from ' + FTableName);
  FDQuery1.Open;

  DBGrid1.Columns[0].Width := 30;
  DBGrid1.Columns[1].Width := 100;
  DBGrid1.Columns[2].Width := 70;
end;

//=============================================================================
//  FireDACを使用した場合のSQLiteのバージョン取得
//  select文でsqlite_version()関数を実行
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LVersionText : string;
begin
  FDQuery2.Close;
  FDQuery2.Connection := FDConnection1;

  FDQuery2.SQL.Clear;
  FDQuery2.Open('select sqlite_version() vrsn');

  if FDQuery2.Eof = False then begin
    LVersionText := FDQuery2.FieldByName('vrsn').AsString;
  end else begin
    LVersionText :='不明';
  end;
  FDQuery2.Close;

  MessageBox(Handle, PChar(LVersionText), 'バージョン', MB_ICONINFORMATION);
end;

end.


FireDAC の場合,実行中の SQLite のバージョンは,以下のように IFDPhysConnectionMetadata インターフェイスからも取得できます.
参考リンクは Delphi 10.0 Seattle のオンラインヘルプの記事です.Delhi XE5 Pro には,DBMS バージョン番号が定義されているユニットはありません.



procedure TForm1.Button1Click(Sender: TObject);
var
  LMetaIntf    : IFDPhysConnectionMetadata;
  LVersionText : string;
begin
  FDConnection1.Connected := False;

  FDConnection1.Params.Clear;
  FDConnection1.Params.Add('DriverID=SQLite');

  LVersionText := '';
  LMetaIntf := FDConnection1.ConnectionMetaDataIntf;
  try
    LVersionText := IntToStr(LMetaIntf.ClientVersion) + sLineBreak
                  + IntToStr(LMetaIntf.ServerVersion);
  finally
    LMetaIntf:= nil;
  end;
end;