.NETで作る!

.NETに関するあれこれ(C#、VB.NET)

SQL Parser(C#) を公開しました

github.com

以前に公開していたSqModel(Sql Builder)にSql Parse 機能を追加しました。

使い方

    [Fact]
    public void Simple()
    {
        using var p = new Parser(@"select a.column_1 as col1, a.column_2 as col2 from table_a as a");
        var q = p.ParseSelectQuery();
        var text = q.ToQuery().CommandText;
        var expect = @"select a.column_1 as col1, a.column_2 as col2
from table_a as a";
        Assert.Equal(expect, text);

        Assert.Equal("a", q.SelectClause.ColumnClauses[0].TableName);
        Assert.Equal("column_1", q.SelectClause.ColumnClauses[0].Value);
        Assert.Equal("col1", q.SelectClause.ColumnClauses[0].AliasName);

        Assert.Equal("table_a", q.FromClause.TableName);
        Assert.Equal("a", q.FromClause.AliasName);
    }

これぐらいのテーブル結合、インラインクエリならパースできます。

select
    a.column_1 as col1
    , a.column_2 as col2
    , ((1+2) * 3) as col3
    , (select b.value from b) as b_value
    , ' comment('')comment ' as comment /* prefix /* nest */ sufix */
from 
    table_a as a
    inner join table_c as c on a.column_1 = c.column_1
    left outer join table_d as d on a.column_2 = d.column_2 and a.column_3 = d.column_3
    left join table_e as e on a.column_4 = e.column_4
where
    a.column_1 = 1
    or  a.column_2 = 2
        var expect = @"select a.column_1 as col1, a.column_2 as col2, ((1+2) * 3) as col3, (select b.value from b) as b_value, ' comment('')comment ' as comment
from table_a as a
inner join table_c as c on a.column_1 = c.column_1
left join table_d as d on a.column_2 = d.column_2 and a.column_3 = d.column_3
left join table_e as e on a.column_4 = e.column_4
where
    a.column_1 = 1 or a.column_2 = 2";

もちろん、トークンも取得できます。テーブル名取得であればこのとおり。

Assert.Equal("table_a", q.FromClause.TableName);

細かく書くときりがないので、どういうものが取れるかはテストコードを参照ください。

今後

機能不足があることは認識しています(たとえばgroup by, order byには対応していません)が、全部のトークンをカバーしてるといつまで立ってもマージできないので、select, from. join, where あたりで一区切りつけてます。 基礎(トークンの切り出し)はしっかりしていますので、今後は対応するトークンを増やしていこうと思います。

何に使えるのか?

SQL文の生成や、SQL文の合成に使用できます。

CTEのWhere文に条件を差し込むとか、SQLをStringで扱ってやるにはシンドイ加工もSqModelなら簡単にできるはず(まだ未対応ですが近日対応できる見込み)

. .