SQLite

Last Updated 2014/02/06


SQLite は汎用性のある簡易的なリレーショナルデータベースです。これを操作するための .NET Framework 対応のライブラリが公開されていますので、.NET Framework および WPF から使うことができます。

SQLite を学ぶ過程で、ライブラリの使い方が重要なのではなく、SQL ステートメントの構文を理解することであることが分かりました。そこで、SQLite の構文をテストするためのツールとして、SQLiteSyntax を自作し、公開しました。


SQLite のマニュアルとライブラリ

SQLite のマニュアルとライブラリなどをダウンロードするサイトは以下のとおりです。

SQLite Download Page

各自の環境に合わせて、ダウンロードすべきファイルを選択してください。私の場合は、以下をダウンロードしました。

カテゴリファイル名サイズ(MB)意味
Source Codesqlite-amalgamation-3080300.zip1.41SQLite のソースファイル
Documentationsqlite-doc-3080300.zip4.39SQLite のマニュアル
Precompiled Binaries for Windowssqlite-shell-win32-x86-3080300.zip0.29コマンドラインシェル
同上sqlite-dll-win32-x86-3080300.zip0.32SQLite ライブラリの DLL
同上sqlite-analyzer-win32-x86-3080300.zip0.68データベースの解析プログラム

sqlite3.exe はコマンドラインシェルで、SQLite をコマンドラインで操作するためのツールです。SQLite の使い方を解説するサイトでよく使われています。実務的に使う機会はないと思いますが、用意しておいてもいいと思います。

Analyzer はデータベースの内容を解析するためのコマンドラインツールです。テストしてみましたが、役に立ちそうな感じはしません。

「SQLite のマニュアル」は、クラスライブラリを含めて、SQLite の使い方のすべてを解説するものです。しかし、残念ながら英文しかありません。


System.Data.SQLite.dll

System.Data.SQLite.dll は、SQLite を .NET Framework/WPF で使うためのライブラリです。以下のサイトに飛んでください。

System.Data.SQLite

このサイトの画面右上にある小さな [Download] を選択し、System.Data.SQLite.dll のソースファイルと環境に合うライブラリをダウンロードしてください。

Note System.Data.SQLite.dll 用の .chm 形式のヘルプファイルは付いているのですが、手抜きが多いですからソースファイルを直接見るしかない場合もあります。再コンパイルまでは必要ないと思いますが、一応用意しておくと便利です。

C# などでは System.Data.SQLite.dll を参照に追加するだけで使えます。なお、WEB サイトなどでは System.Interop.dll も追加しないとエラーになるとの記事がありますが、私の場合、そのようなトラブルはありませんでした。というより、ありえないはずです。ライブラリの開発者がそのような作り方をするはずがないからです。


Windows ツール

SQLite によるデータベースを編集するためのツールがいくつか公開されています。以下は、私がテストしたものです。あちこちのサイトでも利用していますから使えるソフトといっていいと思います。

ところで、どいつもこいつもと言っては失礼ですが、ソフトの使用説明書を付けているものは皆無です。そんなに面倒なのでしょうか。

ソフトの内容については説明しません。他人の作ったソフトを論評するのはどうかと思いますので、各自で判断してください。しかし、私はこれらに満足しませんでした。そこで、自作することにしました。次の項目で説明する SQLiteSyntax です。


SQLiteSyntax

SQLite を扱うときに重要なことは、System.Data.SQLite.dll を使いこなすことではなく、SQL ステートメントをどのように作るかにつきます。そこで、これをテストするためのツールを自作しました。

下図は、SQLiteSyntax を起動したところです。

SQLiteSyntax

SQLitSyntax の入手先は、Software のページに書いておきました。

SQLitSyntax の使い方は、ヘルプファイルを参照してください。初めて使う人は、1 ページだけ読めばだいたいの使い方が分かるようにしましたから迷いはないと思います。

コマンド編集部は完全に日本語に対応しています。また、キーワードの色分けも可能です。


C# で SQLite を扱う

System.Data.SQlite.dll には多くのクラスが含まれています。しかし、使うものはごく一部です。私もライブラリの全体を知っているわけではありませんが、上記で紹介した SQLiteSyntax で使っているクラスを以下にリストアップします。

これだけです。ほかにも使えば役に立つクラスがあるのかもしれませんが、これ以上は使う必要はないと思います。

データベース接続を開く

データベース接続を開いてから何らかの作業をしたあと、データベース接続を閉じる手順は次のとおりです。

  using System.Data.SQLite; // 名前空間を追加

  var connection = new SQLiteConnection();
  connection.ConnectionString = "Data Source=databaseFilePath;Version=3;";
  connection.Open();

  .... (データベース接続を利用するコード)

  connection.Close();

データベース接続を利用するコードは、SQLiteConnection オブジェクトの Open から Close の間です。

上記のコードの中で、ややこしいのは ConnectionString プロパティの設定です。このプロパティの詳細については、SQLite.NET.chm を見てもらうとして、ConnectString プロパティの必須のパラメータは "Data Source" だけです。"Version" はなくてもかまいません。しかし、コードをあとから見たときに、どのバージョンを対象としたものかを明らかにしておくことはムダではありません。

コマンドを実行し、結果を取得する

SQLiteSyntax で使っているコードを一部を編集して収録します。データベースファイル名("Sample.db")やテーブル名("address")は実状に合わせて適宜変更してください。

以下のコードの中の commandText について補足しておきます。

private void button1_Click(object sender, RoutedEventArgs e)
{
  string databaseFilePath = "Sample.db"; // データベースファイル
  string commandText = "select * from address"; // 前後のホワイトスペースは無視、複数行可能

  SQLiteConnection connection = null;
  SQLiteCommand command = null;
  SQLiteDataReader reader = null;

  try
  {
    connection = new SQLiteConnection();
    connection.ConnectionString = "Data Source=" + databaseFilePath + ";Version=3;";
    connection.Open();

    command = connection.CreateCommand();
    command.CommandText = commandText;
    reader = command.ExecuteReader();
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message, "コマンドの実行");
  }
  finally
  {
    if (command != null)
      command.Dispose();
  }

  if (reader == null)
    return;

  var sb = new StringBuilder();
  var sb2 = new StringBuilder();
  int n = 0;
  var columnList = new List<string>();

  if (reader.HasRows) // コマンドの実行後、行データを持つとき
  {
    while (reader.Read())
    {
      if (reader.FieldCount > n)
      {
        columnList.Add(reader.GetName(n)); // カラム名を取得する
        ++n;
      }

      for (int j = 0; j < reader.FieldCount; ++j) // 行データのフィールド数だけ繰り返す
      {
        object obj = reader.GetValue(j);

        if (obj == null)
          sb2.Append("null ");
        else if (obj.ToString() == "")
          sb2.Append("empty ");
        else if (obj is string)
          sb2.Append(String.Format("{0} ", reader.GetString(j)));
        else
          sb2.Append(String.Format("{0} ", obj));
      }

      sb.AppendLine(sb2.ToString());
      sb2.Clear();
    }

    if (reader != null)
      reader.Close();

    // 結果を textBox に出力する
    textBox.Text = String.Empty;
    var s = String.Empty;

    for (int i = 0; i < columnList.Count; ++i)
    {
      s += columnList[i] + "\t";
    }

    if (columnList.Count > 0)
    {
      textBox.Text = s + "\r\n";
      textBox.Text += "--------------------------------------" + "\r\n";
    }

    textBox.Text += sb.ToString();
  }

  // データベース接続を閉じる
  if (connection != null)
    connection.Close();
}

コマンドの実行結果を DataGrid コントロールに設定する

前の項でコマンドの実行結果は TextBox にテキストとして表示しましたが、ここでは DataGrid に表示します。データを取得するまでは TextBox に表示する部分を除いて前の項と基本的に同じです。なお、DataGrid には ItemsSource を以下のように設定しておいてください。これは、DataGrid の DataContext にデータを設定するためです。

  <DataGrid Name="dataGrid" ItemsSource="{Binding}" />
Note ここでは、WPF を使っています。.NET Framework の DataGridView コントロールでもほぼ同じだろうと思います。テストしていませんが。
private void button2_Click(object sender, RoutedEventArgs e)
{
  string databaseFilePath = "Sample.db";
  string commandText = "select * from address";

  SQLiteConnection connection = null;
  SQLiteCommand command = null;
  SQLiteDataReader reader = null;

  try
  {
    connection = new SQLiteConnection();
    connection.ConnectionString = "Data Source=" + databaseFilePath + ";Version=3;";
    connection.Open();

    command = connection.CreateCommand();
    command.CommandText = commandText;
    reader = command.ExecuteReader();
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message, "コマンドの実行");
  }
  finally
  {
    if (command != null)
      command.Dispose();
  }

  if (reader == null)
    return;

  var sb = new StringBuilder();
  var sb2 = new StringBuilder();
  int n = 0;
  var columnList = new List<string>();

  if (reader.HasRows)
  {
    while (reader.Read())
    {
      if (reader.FieldCount > n)
      {
        columnList.Add(reader.GetName(n));
        ++n;
      }

      for (int j = 0; j < reader.FieldCount; ++j)
      {
        object obj = reader.GetValue(j);

        if (obj == null)
          sb2.Append("null ");
        else if (obj.ToString() == "")
          sb2.Append("empty ");
        else if (obj is string)
          sb2.Append(String.Format("{0} ", reader.GetString(j)));
        else
          sb2.Append(String.Format("{0} ", obj));
      }

      sb.AppendLine(sb2.ToString());
      sb2.Clear();
    }

    if (reader != null)
      reader.Close();
  }

  // データベース接続を閉じる
  if (connection != null)
    connection.Close();

  //----------------------------------------------------------------------------------
  // ここまでは、前の項と同じ(TextBox に出力する部分は除いた)

  if (columnList.Count < 1)
    return;

  DataTable tbl = (DataTable)dataGrid.DataContext;

  if (tbl != null)
  {
    tbl.Columns.Clear();
    tbl.AcceptChanges();
    dataGrid.DataContext = tbl;
  }

  var table = new DataTable();

  // カラム名を設定する
  for (int i = 0; i < columnList.Count; ++i)
  {
    table.Columns.Add(columnList[i]);
  }

  table.AcceptChanges();

  SQLiteDataAdapter adapter = null;

  try
  {
    adapter = new SQLiteDataAdapter(commandText, connection);
    adapter.Fill(table);
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message, "実行結果の表示");
  }
  finally
  {
    if (adapter != null)
    {
      adapter.Dispose();
      adapter = null;
    }
  }

  if (table != null)
  {
    dataGrid.DataContext = null;
    dataGrid.DataContext = table;
  }
}

−以上−