テーブルを作る処理を整理する試み(1)

10個以上のテーブルをアクセスするアプリで、テーブルの管理を楽にしたいと思っていろいろ試したことを記録する。


現状

整理する前の状況は以下のような感じ。
  • C#のソースファイルの中に、SQLの「Create Table」文の文字列がずらずらと書いてある。
  • SQLServer Management Studio(SSMS)が、テーブルから作ってくれるCreate Table文をそのまま貼ってある(らしい)。
  • 初期値が必要なテーブルは、それに続いて、insert文も書いてある。
  • アプリが動くときに、これらのSQLを実行する
  • 何度も実行するとエラーになるので、テーブルの有無を調べて、無ければSQLを実行している
問題と思うことは、下記の通り。
  • SQL文がずらずらと書いてあって読みにくい。
  • どこで何のテーブルを作っているのか、わかりにくい。
  • SSMSが自動生成したSQLに知らないキーワードがずらずらと書いてあるのが気になる。間違いではないのだろうけどなにが書いてあるのかわからない。インデックスや外部参照にいちいち名前を付けて作っているし。
  • とにかくメンテがやりにくい

具体例で示すと、テーブルを作っているC#のソースファイルの全体像が下図。(VisualStudioはソースの全体像を表示できるのだ)。このファイルは2700行もあって、茶色はSQLが書かれた文字列で、ほとんどがSQLとわかる。


これだけSQLだと、外部のテキストファイルにSQLをまとめて、それを実行するようにした方がよさそうな気もする。

ただ、このアプリの制約として、テーブルは同じものを別の名前でたくさん作る必要がある。たとえば、年度ごとにテーブルAをいくつも作る感じ(TableA_2018、TableA_2019のような)。

つまり、SQLは一度動かせば完了ではなくて、年度をパラメータとして、何度も動かす必要があって、外部のSQLファイルにしするのは難しいように思える。(まあ、実行するときにパラメータを渡すようにすればよさそうだけど。)

テーブルごとにクラスを作ってみた

改善の一歩として、テーブルごとにクラスを作ってみた。クラスはテーブル名とテーブルを作るSQLをプロパティとして持つ。アプリの都合によりテーブル名は番号付きの接頭辞が付くという形式。(例)mm001_XXX

internal class mmTable_A : mmTable
{
    internal mmTable_A(int yy)
    {
        this.yy = yy;
        this.tableName = string.Format("mm_A_{0:000}", yy);
        this.sqlCreate = @"
create table [{table_name}] 
(
[A_id] [int] NOT NULL primary key,
[A_実施日] [datetime] NULL,
(中略)
); ";
    }
}

これで、テーブルに関することはクラスで管理できる。基底クラスに、テーブルを作るメソッドや、削除するメソッドがあって、以下のように使う。

List<mmTable> lst = new List<mmTable>()
{
      new mmTable_A(2018),
      new mmTable_B(2018),
      new mmTable_C(2018),
    (中略)
};

foreach (mmTable tbl in lst)
{
     tbl.doCreate();
}

SQL文の文字列がずらずらと書いてある状態よりは、ましになった。

(続く)

コメント

このブログの人気の投稿

varchar をデータ型 numeric に変換中に、算術オーバーフロー エラーが発生しました。