T-SQL の Parse と Generate       2013/03/23 SQLWorld大阪#12       SQLWorld お だ
自己紹介織田 信亮大阪で開発者していますSQLWorld の代表ですhttp://d.hatena.ne.jp/odashinsuke/Twitter:@shinsukeoda
アジェンダParse と Generate って?どうやるの?何に使える?使ってみた!まとめ
このセッションの注意事項全ての機能は紹介出来ません!  紹介するライブラリでは、1000近くの Class, 200近くの  Enum がある  簡単な Parse と Generate に絞ってます。
Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
Parse と Generate Parse (パース)    SQL 文 => 構文毎に分解したデータ構造の集まり Generate (ジェネレート)    構文毎のデータ構造の集まり => SQL 文
Parse                              クエリSELECT 列1, 列2FROM テーブル               SELECT 句    FROM 句                 列1         列...
Generate           クエリ                             SELECT 列1, 列2SELECT 句     FROM 句          FROM テーブル 列1          列2     ...
Parse と Generate Parse (パース)    SQL 文 => 構文毎に分解したデータ構造の集まり Generate (ジェネレート)    構文毎のデータ構造の集まり => SQL 文 Parser (パーサー)    Pa...
Parser と Generator MS から .NET Framework のライブラリとして提供 Microsoft.SqlServer.TransactSql.ScriptDom 名前空間    1世代前は…    Microsoft....
Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
インストールMicrosoft SQL Server 2012 Feature Pack   http://www.microsoft.com/ja-   jp/download/details.aspx?id=29065
準備参照の追加     Microsoft.SqlServer.TransactSql.ScriptDom
Parse してみる TSqlParser クラス   Parse メソッドを使う  using Microsoft.SqlServer.TransactSql.ScriptDom;  using System.Collections.Gene...
Parse してみる (エラー) ParseError クラス   Line, Column, Message プロパティから行、文字位置、エ   ラー内容を取れる   if (errors.Count != 0) {     foreach ...
Generate してみる SqlScriptGenerator クラス   GenerateScript メソッドを使う  var options = new SqlScriptGeneratorOptions() {    KeywordC...
もうちょっと細かいとこまでParser – バージョン毎に用意されてる  TSql80Parser - SQL Server 2000用  TSql90Parser - SQL Server 2005用  TSql100Parser - SQL...
もうちょっと細かいとこまでParse 結果  TSqlFragment – 基底クラス   TSqlScript, TSqlBatch, TSqlStatement, SelectElement, FromClause,   WhereClau...
もうちょっと細かいとこまでVisitor   どちらかのクラスを継承し、目的の Visitor メソッドを   override する   TSqlFragmentVisitor      呼び出される Visitor メソッドのパラメータは継...
もうちょっと細かいとこまで例:SELECT で指定している項目の数を数える  http://msdn.microsoft.com/ja-  jp/library/microsoft.sqlserver.transactsql.scriptdom...
もうちょっと細かいとこまでTSqlFragmentVisitor   SELECT で指定している項目全ての件数を数える Visitor   public class SelectElementVisitor : TSqlFragmentVis...
もうちょっと細かいとこまでTSqlConcreteFragmentVisitor   SELECT で指定している “*” の件数を数える Visitor   public class SelectStarVisitor : TSqlFragm...
もうちょっと細かいとこまでカスタム Visitor を利用する var q = @"SELECT @Id = A.Id, @Name = B.Name FROM ( SELECT * FROM Table1 WHERE Id = 1) A   ...
もうちょっと細かいとこまでGenerator – バージョン毎に用意されてる  Sql80ScriptGenerator - SQL Server 2000用  Sql90ScriptGenerator - SQL Server 2005用  ...
もうちょっと細かいとこまでTSqlFragment を組み立てて、クエリを生成する 「もうちょっと」 で済まないくらい大        変!!      お勧めはしない   http://d.hatena.ne.jp/odashinsuke/2...
裏では何使ってるの?antlr を使ってると思います  http://www.antlr.org/
Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
MSDN に掲載されているサンプルチュートリアル: SQL 用のカスタムの静的コード分析規則アセンブリを作成する  http://msdn.microsoft.com/ja-  jp/library/dd172127%28v=vs.100%29...
何に使えるの?   アイデア募集中!
何に使えるの?クエリの検証  構文エラーの検出  コーディング規約のチェッククエリの書式設定/統一クエリの部分抽出動的なクエリ生成  クエリの改造
クエリの検証構文エラーの検出  実DB が無い環境でも SQL の構文が正しいか判定出来る  注意点としてオブジェクトの存在チェックは出来ない!  SQL Server のバージョン毎に構文チェックが可能なので、移  行検証時に使えるかも  S...
クエリの検証コーディング規約のチェック  例えば…  DELETE は使わない(論理削除)  マスタテーブル(MST_~)は inner join とか  漏れやすい項目の検証  SELECT 文に ORDER BY が存在していないクエリの検...
クエリの書式設定/統一クエリのフォーマット  キーワードの大文字/小文字化  識別子の [] 囲み  インデント  改行
クエリの部分抽出サブクエリだけ抜き出すSELECT の結果カラムだけ抜き出すINSERT – SELECT から SELECT だけ抜き出す  INSERT 実行前に更新対象を確認(クエリ自体は1つで可能)
動的なクエリ生成クエリの改造  ER => DDL (CREATE TABLE) で共通的なカラムの追加  SELECT で共通的なカラムの追加  COUNT(*) OVER() AS [全件数]  INSERT/UPDATE で共通的なカラム...
Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
ScriptDom のサンプルサイト ScriptDom Sample    http://scriptdomsample.azurewebsites.net/    クエリの書式設定/統一    クエリの部分抽出    クエリの改造
ビルド時の SQL 検証MSBuild のタスクとして作成する  プロジェクト内に存在する .sql ファイルで SELECT 文の物  を対象に ORDER BY が存在しなかったらエラーとする
まとめT-SQL には、MS 公式の Parser/Generator があるSQL Server 2000, 2005, 2008, 2012 の4バージョン面白そうではあるけど、どこで/何に使うのかはアイデアが要るかも
参考資料Microsoft SQL Server 2012 Feature Packhttp://www.microsoft.com/ja-jp/download/details.aspx?id=29065Microsoft.SqlServer...
参考資料 (ScriptDom を使ってる)チュートリアル: SQL 用のカスタムの静的コード分析規則アセンブリを作成するhttp://msdn.microsoft.com/ja-jp/library/dd172127%28v=vs.100%2...
Upcoming SlideShare
Loading in …5
×

T sql の parse と generator

1,569 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,569
On SlideShare
0
From Embeds
0
Number of Embeds
223
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

T sql の parse と generator

  1. 1. T-SQL の Parse と Generate 2013/03/23 SQLWorld大阪#12 SQLWorld お だ
  2. 2. 自己紹介織田 信亮大阪で開発者していますSQLWorld の代表ですhttp://d.hatena.ne.jp/odashinsuke/Twitter:@shinsukeoda
  3. 3. アジェンダParse と Generate って?どうやるの?何に使える?使ってみた!まとめ
  4. 4. このセッションの注意事項全ての機能は紹介出来ません! 紹介するライブラリでは、1000近くの Class, 200近くの Enum がある 簡単な Parse と Generate に絞ってます。
  5. 5. Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
  6. 6. Parse と Generate Parse (パース) SQL 文 => 構文毎に分解したデータ構造の集まり Generate (ジェネレート) 構文毎のデータ構造の集まり => SQL 文
  7. 7. Parse クエリSELECT 列1, 列2FROM テーブル SELECT 句 FROM 句 列1 列2 テーブル
  8. 8. Generate クエリ SELECT 列1, 列2SELECT 句 FROM 句 FROM テーブル 列1 列2 テーブル
  9. 9. Parse と Generate Parse (パース) SQL 文 => 構文毎に分解したデータ構造の集まり Generate (ジェネレート) 構文毎のデータ構造の集まり => SQL 文 Parser (パーサー) Parse してくれる便利なやつ Generator (ジェネレーター) Generate してくれる良いやつ
  10. 10. Parser と Generator MS から .NET Framework のライブラリとして提供 Microsoft.SqlServer.TransactSql.ScriptDom 名前空間 1世代前は… Microsoft.Data.Schema.ScriptDom Microsoft.Data.Schema.ScriptDom.Sql SQL Server 2012 Feature Pack の 「Transact-SQL ScriptDom」 をインストール SQL Server は不要
  11. 11. Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
  12. 12. インストールMicrosoft SQL Server 2012 Feature Pack http://www.microsoft.com/ja- jp/download/details.aspx?id=29065
  13. 13. 準備参照の追加 Microsoft.SqlServer.TransactSql.ScriptDom
  14. 14. Parse してみる TSqlParser クラス Parse メソッドを使う using Microsoft.SqlServer.TransactSql.ScriptDom; using System.Collections.Generic; using System.IO; var parser = new TSql110Parser(false); IList<ParseError> errors; TSqlFragment parsed; using (var query = new StringReader("select * from Table1")) { parsed = parser.Parse(query, out errors); }
  15. 15. Parse してみる (エラー) ParseError クラス Line, Column, Message プロパティから行、文字位置、エ ラー内容を取れる if (errors.Count != 0) { foreach (var error in errors) { System.Console.WriteLine("{0}行目 {1} 文字目 {2}", error.Line, error.Column, error.Message); } }
  16. 16. Generate してみる SqlScriptGenerator クラス GenerateScript メソッドを使う var options = new SqlScriptGeneratorOptions() { KeywordCasing = KeywordCasing.Uppercase, IncludeSemicolons = true, NewLineBeforeFromClause = true, NewLineBeforeOrderByClause = true, NewLineBeforeWhereClause = true }; var generator = new Sql110ScriptGenerator(options); string generated; generator.GenerateScript(parsed, out generated);
  17. 17. もうちょっと細かいとこまでParser – バージョン毎に用意されてる TSql80Parser - SQL Server 2000用 TSql90Parser - SQL Server 2005用 TSql100Parser - SQL Server 2008用 TSql110Parser - SQL Server 2012用 バージョンが違うとエラーになる構文 も…
  18. 18. もうちょっと細かいとこまでParse 結果 TSqlFragment – 基底クラス TSqlScript, TSqlBatch, TSqlStatement, SelectElement, FromClause, WhereClause, Identifier, CreateTableStatement, 等々 800個近い継 承したクラスがある DML に限らず、DDL や DBCC 等の全ての T-SQL に対応している「は ず!」 Visitor パターンになっているので、Visitor を実装すれば 色々出来る
  19. 19. もうちょっと細かいとこまでVisitor どちらかのクラスを継承し、目的の Visitor メソッドを override する TSqlFragmentVisitor 呼び出される Visitor メソッドのパラメータは継承した物も含む TSqlConcreteFragmentVisitor Visitor メソッドのパラメータ型は厳密
  20. 20. もうちょっと細かいとこまで例:SELECT で指定している項目の数を数える http://msdn.microsoft.com/ja- jp/library/microsoft.sqlserver.transactsql.scriptdom.selectelement.aspx SELECT @Id = A.Id, @Name = B.Name FROM ( SELECT * FROM Table1 WHERE Id = 1) A INNER JOIN Table2 B ON ( A.USERID = B.ID )
  21. 21. もうちょっと細かいとこまでTSqlFragmentVisitor SELECT で指定している項目全ての件数を数える Visitor public class SelectElementVisitor : TSqlFragmentVisitor { public int Count { get; set; } public override void Visit(SelectElement node) { Count++; base.Visit(node); } }
  22. 22. もうちょっと細かいとこまでTSqlConcreteFragmentVisitor SELECT で指定している “*” の件数を数える Visitor public class SelectStarVisitor : TSqlFragmentVisitor { public int Count { get; set; } public override void Visit(SelectStarExpression node) { Count++; base.Visit(node); } }
  23. 23. もうちょっと細かいとこまでカスタム Visitor を利用する var q = @"SELECT @Id = A.Id, @Name = B.Name FROM ( SELECT * FROM Table1 WHERE Id = 1) A INNER JOIN Table2 B ON ( A.USERID = B.ID )"; var f = new TSql110Parser(false) .Parse(new StringReader(q), out errors); var v1 = new SelectElementVisitor(); var v2 = new SelectStarVisitor(); f.Accept(v1); f.Accept(v2); Console.WriteLine(v1.Count); // 3 Console.WriteLine(v2.Count); // 1
  24. 24. もうちょっと細かいとこまでGenerator – バージョン毎に用意されてる Sql80ScriptGenerator - SQL Server 2000用 Sql90ScriptGenerator - SQL Server 2005用 Sql100ScriptGenerator - SQL Server 2008用 Sql110ScriptGenerator - SQL Server 2012用 イマイチ違いが判らず …
  25. 25. もうちょっと細かいとこまでTSqlFragment を組み立てて、クエリを生成する 「もうちょっと」 で済まないくらい大 変!! お勧めはしない http://d.hatena.ne.jp/odashinsuke/20130224/1361714459
  26. 26. 裏では何使ってるの?antlr を使ってると思います http://www.antlr.org/
  27. 27. Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
  28. 28. MSDN に掲載されているサンプルチュートリアル: SQL 用のカスタムの静的コード分析規則アセンブリを作成する http://msdn.microsoft.com/ja- jp/library/dd172127%28v=vs.100%29.aspxVisual Studio 2008/2010 でのコード解析 で 「WAITFORDELAY」 が使用されているか検出するチュートリアル
  29. 29. 何に使えるの? アイデア募集中!
  30. 30. 何に使えるの?クエリの検証 構文エラーの検出 コーディング規約のチェッククエリの書式設定/統一クエリの部分抽出動的なクエリ生成 クエリの改造
  31. 31. クエリの検証構文エラーの検出 実DB が無い環境でも SQL の構文が正しいか判定出来る 注意点としてオブジェクトの存在チェックは出来ない! SQL Server のバージョン毎に構文チェックが可能なので、移 行検証時に使えるかも SQL Server の Ver UP や 他社DB (Oracle 等)からの移行
  32. 32. クエリの検証コーディング規約のチェック 例えば… DELETE は使わない(論理削除) マスタテーブル(MST_~)は inner join とか 漏れやすい項目の検証 SELECT 文に ORDER BY が存在していないクエリの検出 スキーマ指定漏れ 定型的な条件の漏れ (DELETE_FLG = 0 とか) COLLATE 指定
  33. 33. クエリの書式設定/統一クエリのフォーマット キーワードの大文字/小文字化 識別子の [] 囲み インデント 改行
  34. 34. クエリの部分抽出サブクエリだけ抜き出すSELECT の結果カラムだけ抜き出すINSERT – SELECT から SELECT だけ抜き出す INSERT 実行前に更新対象を確認(クエリ自体は1つで可能)
  35. 35. 動的なクエリ生成クエリの改造 ER => DDL (CREATE TABLE) で共通的なカラムの追加 SELECT で共通的なカラムの追加 COUNT(*) OVER() AS [全件数] INSERT/UPDATE で共通的なカラムの追加 更新日/更新者 等
  36. 36. Parse と Generate って?どうやるの?何に使える?使ってみた!まとめ
  37. 37. ScriptDom のサンプルサイト ScriptDom Sample http://scriptdomsample.azurewebsites.net/ クエリの書式設定/統一 クエリの部分抽出 クエリの改造
  38. 38. ビルド時の SQL 検証MSBuild のタスクとして作成する プロジェクト内に存在する .sql ファイルで SELECT 文の物 を対象に ORDER BY が存在しなかったらエラーとする
  39. 39. まとめT-SQL には、MS 公式の Parser/Generator があるSQL Server 2000, 2005, 2008, 2012 の4バージョン面白そうではあるけど、どこで/何に使うのかはアイデアが要るかも
  40. 40. 参考資料Microsoft SQL Server 2012 Feature Packhttp://www.microsoft.com/ja-jp/download/details.aspx?id=29065Microsoft.SqlServer.TransactSql.ScriptDom 名前空間http://msdn.microsoft.com/ja-jp/library/hh215705.aspxVisual Studio のデータベース機能の API リファレンスhttp://msdn.microsoft.com/ja-jp/library/dd193281(v=vs.100).aspxANTLRhttp://www.antlr.org/
  41. 41. 参考資料 (ScriptDom を使ってる)チュートリアル: SQL 用のカスタムの静的コード分析規則アセンブリを作成するhttp://msdn.microsoft.com/ja-jp/library/dd172127%28v=vs.100%29.aspxSQLPSX (PowerShell2 系/1世代前の ScriptDom)http://sqlpsx.codeplex.com/

×