ScriptDom クエリ生成時に識別子を[]で囲む
SqlScriptGenerator クラス (Microsoft.SqlServer.TransactSql.ScriptDom) でクエリを生成する際のオプション
SqlScriptGeneratorOptions クラス (Microsoft.SqlServer.TransactSql.ScriptDom) では、識別子を で囲むオプションがありません。
ですが、ちょっと工夫をすることで識別子を で囲むことが出来ます。
こんな Visitor を実装して、
public class IdentifierSquareQuote : TSqlConcreteFragmentVisitor { public override void Visit(Identifier node) { if (node.QuoteType == QuoteType.NotQuoted) { node.QuoteType = QuoteType.SquareBracket; } base.Visit(node); } }
パースした TSqlFragment に食わすことで [] で囲む事が出来ます。
using Microsoft.SqlServer.TransactSql.ScriptDom; using System; using System.Collections.Generic; using System.IO; class Program { static void Main(string[] args) { var parser = new TSql110Parser(false); IList<ParseError> errors; TSqlFragment parsed; using (var reader = new StringReader(@"select top (10) id from Table1")) { parsed = parser.Parse(reader, out errors); } parsed.Accept(new IdentifierSquareQuote()); var generator = new Sql110ScriptGenerator(); string query; generator.GenerateScript(parsed, out query); Console.WriteLine(query); Console.ReadKey(); } }
ただ、これだけだと Function の名前も囲ってしまい、意図していないクエリになってしまいます。
上のコードのクエリを書き換えると…
using (var reader = new StringReader(@"select top (10) id, getdate() from Table1")) { parsed = parser.Parse(reader, out errors); }
これは困るので Visitor の実装を少し変えて Function の名前は省くようにしてみましょう。
public class IdentifierSquareQuote : TSqlConcreteFragmentVisitor { private List<TSqlFragment> functionName = new List<TSqlFragment>(); public override void Visit(FunctionCall node) { functionName.Add(node.FunctionName); base.Visit(node); } public override void Visit(Identifier node) { if (!functionName.Any(n => n == node)) { if (node.QuoteType == QuoteType.NotQuoted) { node.QuoteType = QuoteType.SquareBracket; } } base.Visit(node); } }
これで Function の名前に関しては大丈夫ですね!