2016年1月31日日曜日

[SQLite]外部キープラグマの確認

SQLiteでは、デフォルトで外部キーチェックが無効となっています。

そもそも外部キー制約が取り入れられたのがVer3.6.19からです。
2009-10-14リリースからですね。
https://www.sqlite.org/oldnews.html

せっかくなので確認してみます。
まずは、デフォルトでの動作確認です。
従業員テーブルと、部署テーブルを定義してから
部署テーブルにデータをいれずに、従業員テーブルにデータを
入れて外部参照エラーを起こさせるシナリオです。
using System;
using System.Data;
using System.Data.SQLite;

namespace SampleCode
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (SQLiteConnection con = new SQLiteConnection("Data Source=:memory:"))
                {
                    con.Open();

                    using (SQLiteCommand cmd = con.CreateCommand())
                    {
                        // 部署テーブルの作成
                        cmd.CommandText = "CREATE TABLE [Department](" +
                                          "[id]    INTEGER NOT NULL PRIMARY KEY, " +
                                          "[name]  TEXT    NOT NULL" +
                                          ");";
                        cmd.ExecuteNonQuery();

                        // 従業員テーブルの作成
                        cmd.CommandText = "CREATE TABLE [Employee](" +
                                          "[id]     INTEGER PRIMARY KEY AUTOINCREMENT, " +
                                          "[name]   TEXT    NOT NULL, " +
                                          "[depID]  INTEGER NOT NULL," +
                                          "FOREIGN KEY([id]) REFERENCES [Employee]([depID]) " +
                                          ");";
                        cmd.ExecuteNonQuery();

                        cmd.CommandText = "INSERT INTO [Employee] (name, depID) VALUES('hoge', 100);";
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

何事もなく終了します。
そこで、Foreign Keyプラグマを有効にします。
https://www.sqlite.org/pragma.html#pragma_foreign_keys

下記のように、SQL文として実行することでも有効にできますが・・・
cmd.CommandText = "PRAGMA foreign_keys = ON;";
cmd.ExecuteNonQuery();

接続文字列に指定することもできます。
[SQLite]DB作成および接続


SQLiteConnection con = new SQLiteConnection("Data Source=:memory:;Foreign Keys=True")
これで実行すると、下記のようにエラーになります
SQL logic error or missing database
foreign key mismatch - "Employee" referencing "Employee"

0 件のコメント:

コメントを投稿