【試して覚える】SQLiteで「超簡単」SQL入門~ツール編

当ページのリンクには広告が含まれています。

前回の記事でC#を使ったSQLの共通クラスをご紹介しました。

せっかくなので、今回はそれを使った簡易ツールを作成して公開することにしました。

また、今後はSQLを覚えたいという方を対象に、このツールを使ったSQLの入門記事を掲載していきますので、是非ご活用ください。

この記事では、ツールの使い方とソースコード(C#で作成)の解説を行っています。

ソースコードに興味が無い方は、前半の使い方だけ目を通して頂き、あとはツールをダウンロードして次の記事に進んでいただければと思います。

目次

ツールの概要

次の動画を見て頂いたら、だいたい分かると思います。

基本は「SQL編集」欄に任意のSQLを入力して、「実行」ボタンをクリックすることで、そのSQLを実行します。

問い合わせ用SQL(Query)を実行した場合は、結果が「実行結果」欄に表示されます。

では、簡単に操作についての解説を行っていきます。

「初期化」ボタン

テストデータとして、「商品マスタ」、「商品仕様」、「売上データ」の3つを用意しています。

「初期化」ボタンを押すことで、データベースが削除され、これら3つのデータがデータベースに格納されます。

Insert、Update、deleteを試してみて、データがぐちゃぐちゃになったら、このボタンを押すと初期状態に戻るという訳です。

尚、このボタンで消されるのは上記3テーブルのみになります。

もしご自身でテーブルを作成している場合は、SQLiteのデータベースファイルを直接削除して下さい。

また、削除の際はプログラムを一旦終了た状態で行って下さい。

「実行ボタン」

SQL編集欄に書かれたSQLを実行します。

問い合わせ用SQL(Query文)の場合は、結果を「実行結果」に一覧表示します。

また、レコード件数に右上に表示されるようになっています。

(画面の例では93件)

テーブル一覧のクリックとダブルクリック

テーブル一覧をクリック/ダブルクリックすると次の動作になります。

  • クリック⇒カラム一覧にカラム名とデータ型を表示
  • ダブルクリック⇒実行結果にそのテーブルの全レコードを表示

テーブルに加えた変更がすぐに確認できるので、学習で便利な機能です。

カラム一覧

カラム一覧には、カラム名とデータ型が表示されます。

SQLite の特長として、カラム名にデータ型を指定せずテーブルを作成することが可能なのですが、この場合、データ型は空白になります。

テストデータについて

テストデータはDataフォルダに格納されています。

現時点では「商品マスタ.csv」、「商品仕様.csv」、「売上データ.csv」の3つを用意しましたが、実は「初期化」ボタンをクリックすると、Dataフォルダの中にあるCSVを全て読み込むようになっています。

もしご自身でテストデータを作りたい場合は、ここにおいて下さい。

また、CSVを読み込む際は、一旦テーブルを削除してから作り直すという動作をしているため、消したくないテーブルがあれば、このフォルダから対応するCSVを削除して下さい。

プログラムのダウンロード場所

以下のリンクからダウンロードして下さい。

尚、ソースは含まれていません。

以上で準備は完了です。

C#のソースに興味のない方は、次の記事に移動して下さい。

興味があるかたは続けてどうぞ。

プロジェクト一式

Visual Studio 2019 で作ったプロジェクトは次のリンクからダウンロードできます。

このプロジェクトにはSQLite のライブラリが同梱されていません。

ビルドする時は、必ず Nuget から SQLiteをインストールして下さいね。

ソースコード

以下がソースコードになります。

SQLiteのアクセスクラス(SQLiteUtil)は1つ前の記事で解説していますので、ここでは割愛します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using CommonClass;


namespace SQLiteLearn
{
    public partial class MainForm : Form
    {
        private SQLiteUtil _sqlite;
        private string SQLITE_DB = @".\SQLiteLean.sqlite";
        private string CSV_DIR = @".\Data";

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// フォームロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {

            _sqlite = new SQLiteUtil(SQLITE_DB);

            if (File.Exists(SQLITE_DB) == false)
            {
                SQLiteInitialize();
            }
            ShowTableList();
            ShowGridLineNum(uxDataGridView);
        }

        /// <summary>
        /// 初期化ボタンクリック処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxInitialize_Click(object sender, EventArgs e)
        {
            if (File.Exists(SQLITE_DB))
            {
                if (MessageBox.Show("データベースが初期化されます。よろしいですか?",
                    "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel)
                {
                    return;
                }
            }
            SQLiteInitialize();
        }

        /// <summary>
        /// 実行ボタンクリック処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxExecute_Click(object sender, EventArgs e)
        {
            ExecuteSql(uxSqlEditor.Text);
        }

        /// <summary>
        /// SQLの実行とDataGridViewへの表示
        /// </summary>
        /// <param name="sql"></param>
        private void ExecuteSql(string sql)
        {
            try
            {
                var dt = _sqlite.ExecuteReader(sql);
                uxRecordCount.Text = dt.Rows.Count.ToString();
                uxDataGridView.Columns.Clear();
                uxDataGridView.DataSource = dt;
                uxDataGridView.AlternatingRowsDefaultCellStyle.BackColor = Color.Aqua;
                ShowTableList();
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// SQLiteのDBを作成
        /// </summary>
        private void SQLiteInitialize()
        {
            foreach (var file in Directory.GetFiles(CSV_DIR, "*.csv"))
            {
                var tablename = Path.GetFileNameWithoutExtension(file);
                _sqlite.DropTable(tablename);
                var dt = LoadCsv(file);
                var fields = _sqlite.CreateFieldList(dt);
                _sqlite.CreateTable(tablename, string.Join(",", fields));
                _sqlite.SetData(tablename, dt);
            }

            ShowTableList();
        }

        /// <summary>
        /// CSV読み込み(テスト用CSVを読み込むための簡易版)
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private DataTable LoadCsv(string filename)
        {
            var lines = File.ReadAllLines(filename, Encoding.GetEncoding("shift-jis"));

            DataTable dt = new DataTable();
            dt.Columns.AddRange(lines[0].Split(',').Select(i => new DataColumn(i.Trim())).ToArray());
            Enumerable.Range(1, lines.Length - 1).Select(i => dt.Rows.Add(dt.NewRow().ItemArray = lines[i].Split(','))).ToArray();

            return dt;

        }

        /// <summary>
        /// テーブル一覧の表示
        /// </summary>
        private void ShowTableList()
        {
            uxTableList.Items.Clear();
            uxTableList.Items.AddRange(_sqlite.GetTableList());
            uxTableCount.Text = uxTableList.Items.Count.ToString();
        }

        /// <summary>
        /// テーブル一覧のクリック処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxTableList_Click(object sender, EventArgs e)
        {
            var name = uxTableList.SelectedItem;
            if (name != null)
            {
                uxColumnList.Items.Clear();
                var dt = _sqlite.GetColumnInfo(name.ToString());
                uxColumnList.Items.AddRange(dt.AsEnumerable().Select(i=>string.Format("{0}   {1}",i["name"],i["type"])).ToArray());
                uxColumnCount.Text = uxColumnList.Items.Count.ToString();
            }
        }

        /// <summary>
        /// テーブル一覧のダブルクリック処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxTableList_DoubleClick(object sender, EventArgs e)
        {
            var name = uxTableList.SelectedItem;
            if (name != null)
            {
                ExecuteSql(string.Format("select * from {0}", uxTableList.SelectedItem.ToString()));
            }
        }

        /// <summary>
        /// DataGridViewへの行番号表示
        /// </summary>
        /// <param name="dgv"></param>
        private void ShowGridLineNum(DataGridView dgv)
        {
            dgv.CellPainting += (s, e) =>
            {
                //列ヘッダーかどうか調べる
                if (e.ColumnIndex < 0 && e.RowIndex >= 0)
                {
                    //セルを描画する
                    e.Paint(e.ClipBounds, DataGridViewPaintParts.All);

                    //行番号を描画する範囲を決定する
                    //e.AdvancedBorderStyleやe.CellStyle.Paddingは無視しています
                    Rectangle indexRect = e.CellBounds;
                    indexRect.Inflate(-2, -2);
                    //行番号を描画する
                    TextRenderer.DrawText(e.Graphics,
                        (e.RowIndex + 1).ToString(),
                        e.CellStyle.Font,
                        indexRect,
                        e.CellStyle.ForeColor,
                        TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
                    //描画が完了したことを知らせる
                    e.Handled = true;
                }
            };
        }
    }
}

ソースコードの解説

今回は VisualStudio2019 のWindowsFormアプリをC#を使って作成しています。

詳細はソースコードを見て頂くと分かると思いますが、ポイントをいくつか解説しておきます。

フォームロード処理

フォームロードのイベントハンドラでは、SQLiteUtil クラスのインスタンスを生成した後で、SQLITEのデータベースファイルの存在チェックを行い、存在しない場合はSQLiteInitianaize メソッドを呼び出しています。

        private void MainForm_Load(object sender, EventArgs e)
        {

            _sqlite = new SQLiteUtil(SQLITE_DB);

            if (File.Exists(SQLITE_DB) == false)
            {
                SQLiteInitialize();
            }
            ShowTableList();
            ShowGridLineNum(uxDataGridView);
        }

SQLiteInitializeメソッド

SQLiteInitianaizeメソッドは、データベースファイルを新規作成し、Dataフォルダ直下のCSVを全てデータベースファイルに読み込むという処理を行っています。

DSV_DIRという名前で定義されたフォルダ(実際はDataフォルダ)から拡張子CSVのファイルを全て読み込み、まずテーブルを削除した後で、CSVを読み込んではテーブルを作成するという処理を繰り返しています。

そして、最後に SowiTableListメソッドを呼び出し、テーブル一覧にテーブル名を表示しています。

        private void SQLiteInitialize()
        {
            foreach (var file in Directory.GetFiles(CSV_DIR, "*.csv"))
            {
                var tablename = Path.GetFileNameWithoutExtension(file);
                _sqlite.DropTable(tablename);
                var dt = LoadCsv(file);
                var fields = _sqlite.CreateFieldList(dt);
                _sqlite.CreateTable(tablename, string.Join(",", fields));
                _sqlite.SetData(tablename, dt);
            }

            ShowTableList();
        }

ExecuteSqlメソッド

実行ボタンをクリックすると、このExecuteSqlメソッドが呼び出されます。

ここでは、SQLを実行し、その結果をDataGridViewに表示しています。

間違ったSQLを実行して例外が発生してもプログラムが異常終了しないように、Try~Catchで例外処理を行っています。

uxDataGridView.AlternatingRowsDefaultCellStyle.BackColor は、奇数行の背景色を設定するプロパティです。

        private void ExecuteSql(string sql)
        {
            try
            {
                var dt = _sqlite.ExecuteReader(sql);
                uxRecordCount.Text = dt.Rows.Count.ToString();
                uxDataGridView.DataSource = dt;
                uxDataGridView.AlternatingRowsDefaultCellStyle.BackColor = Color.Aqua;
                ShowTableList();
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

LoadCsvメソッド

CSVを読み込んでDataTableとして返すメソッドです。

1行目にヘッダがあり、各項目はカンマで区切られ、項目内には改行、ダブルクォーテーション、カンマが含まれないという前提で作った簡易版のCSV読み込みメソッドです。

        private DataTable LoadCsv(string filename)
        {
            var lines = File.ReadAllLines(filename, Encoding.GetEncoding("shift-jis"));

            DataTable dt = new DataTable();
            dt.Columns.AddRange(lines[0].Split(',').Select(i => new DataColumn(i.Trim())).ToArray());
            Enumerable.Range(1, lines.Length - 1).Select(i => dt.Rows.Add(dt.NewRow().ItemArray = lines[i].Split(','))).ToArray();

            return dt;

        }

1行目のヘッダをカンマで分解し、DataTableのDataColumnをセットするための処理をLinqを使って次の様に処理しています。

dt.Columns.AddRange(lines[0].Split(',').Select(i => new DataColumn(i.Trim())).ToArray());

また、2行目以降については、同じくLinqで次のように処理しています。

Enumerable.Range(1, lines.Length - 1).Select(i => dt.Rows.Add(dt.NewRow().ItemArray = lines[i].Split(','))).ToArray();

DataGridViewの行番号表示

このサイトの記事ではしばしば登場しますが、DataGridViewに行番号を表示するための処理をメソッド化して使用しています。

引数にDataGridViewを指定するだけで、行番号が表示されるようになります。

       private void ShowGridLineNum(DataGridView dgv)
        {
            dgv.CellPainting += (s, e) =>
            {
                //列ヘッダーかどうか調べる
                if (e.ColumnIndex < 0 && e.RowIndex >= 0)
                {
                    //セルを描画する
                    e.Paint(e.ClipBounds, DataGridViewPaintParts.All);

                    //行番号を描画する範囲を決定する
                    //e.AdvancedBorderStyleやe.CellStyle.Paddingは無視しています
                    Rectangle indexRect = e.CellBounds;
                    indexRect.Inflate(-2, -2);
                    //行番号を描画する
                    TextRenderer.DrawText(e.Graphics,
                        (e.RowIndex + 1).ToString(),
                        e.CellStyle.Font,
                        indexRect,
                        e.CellStyle.ForeColor,
                        TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
                    //描画が完了したことを知らせる
                    e.Handled = true;
                }
            };

まとめ

今回はSQLiteアクセスクラスを使ったSQL学習用の簡易ツールを紹介しました。

ソースコード付きですので、興味がある方は色々と手を加えてお使いください。

次回からしばらくの間は、このツールを使ってSQLの基本について解説していきたいと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次