SQL Parser(C#) を公開しました
以前に公開していた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 あたりで一区切りつけてます。 基礎(トークンの切り出し)はしっかりしていますので、今後は対応するトークンを増やしていこうと思います。
何に使えるのか?
CTEのWhere文に条件を差し込むとか、SQLをStringで扱ってやるにはシンドイ加工もSqModelなら簡単にできるはず(まだ未対応ですが近日対応できる見込み)