SQL Database(旧SQL Azure) がサポートしていないクエリを、実際にクエリを実行せずに知りたいなーというのがきっかけです。
サポート状況はここらへんを見ています。
関数 (Azure SQL データベース)
構文やファンクション等のサポート状況が MSDN や TechNet のドキュメントベースで提供されていますが、ドキュメント見ないと判断出来ないのはちょっと不便だなと。
で、ScriptDom を使って出来ないかな~と試してるところです。
こんな感じ。
using System; using System.Collections.Generic; using Microsoft.SqlServer.TransactSql.ScriptDom; using ScriptDom.SqlDatabase; namespace ScriptDom.SqlDatabase { public class SqlDatabaseVerifyVisitor : TSqlFragmentVisitor { public List<TSqlFragment> Errors { get; private set; } public SqlDatabaseVerifyVisitor() { Errors = new List<TSqlFragment>(); } /// <summary> /// 行セット関数(Rowset Functions) /// </summary> /// <param name="node"></param> public override void Visit(TableReferenceWithAlias node) { if (node.IsUnsupport()) { Errors.Add(node); } base.Visit(node); } /// <summary> /// 構成関数(Configuration Functions) /// </summary> /// <param name="node"></param> public override void Visit(GlobalVariableExpression node) { if (node.IsUnsupport()) { Errors.Add(node); } base.Visit(node); } /// <summary> /// 分析関数(Analytic Functions) /// </summary> /// <param name="node"></param> public override void Visit(FunctionCall node) { if (node.IsUnsupport()) { Errors.Add(node); } base.Visit(node); } } }
using System; using System.Collections.Generic; using Microsoft.SqlServer.TransactSql.ScriptDom; namespace ScriptDom.SqlDatabase { public static class Unsupports { /// <summary> /// 行セット関数(Rowset Functions) /// </summary> /// <param name="node"></param> /// <returns></returns> public static bool IsUnsupport(this TableReferenceWithAlias node) { switch (node.GetType().Name) { case "FullTextTableReference": // CONTAINSTABLE/FREETEXTTABLE case "AdHocTableReference": // OPENDATASOURCE case "OpenQueryTableReference": // OPENQUERY case "OpenRowsetTableReference": // OPENROWSET case "OpenXmlTableReference": // OPENROWSET return true; default: return false; } } /// <summary> /// 構成関数(Configuration Functions) /// </summary> /// <param name="node"></param> /// <returns></returns> public static bool IsUnsupport(this GlobalVariableExpression node) { switch (node.Name.ToUpper()) { case "@@MAX_CONNECTIONS": case "@@REMSERVER": case "@@SERVICENAME": return true; default: return false; } } /// <summary> /// 分析関数(Analytic Functions) /// </summary> /// <param name="node"></param> /// <returns></returns> public static bool IsUnsupport(this FunctionCall node) { switch (node.FunctionName.Value.ToUpper()) { case "COME_DIST": case "FIRST_VALUE": case "LAG": case "LAST_VALUE": case "LEAD": case "PERCENTILE_CONT": case "PERCENTILE_DISC": case "PERCENT_RANK": return true; default: return false; } } } }
ただ今のところ自分で使う予定も無いので、最終どんな形で実行出来るようにするのか何も考えてないです。
.targets ファイルとか作って MSBuild にするのか、CUI な.exe にしてしまうのかどうしようかな~。