-
-
Save Hugoberry/a493d98fd4384858fe57cb0c7b322dbe to your computer and use it in GitHub Desktop.
Some examples with Microsoft.SqlServer.TransactSql.ScriptDom and TSql generation and parsing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.SqlServer.TransactSql.ScriptDom; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace TransactSqlScriptDomTest | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var sql = @"select firstname, lastname FROM persons as p; | |
SELECT id, name FROM companies; | |
select s.test from (select 'hello' as test) as s;"; | |
TSqlParser parser = new TSql120Parser(true); | |
IList<ParseError> parseErrors; | |
TSqlFragment sqlFragment = parser.Parse(new StringReader(sql), out parseErrors); | |
if (parseErrors.Count > 0) Console.WriteLine("Errors:"); | |
parseErrors.Select(e => e.Message.Indent(2)).ToList().ForEach(Console.WriteLine); | |
OwnVisitor visitor = new OwnVisitor(); | |
sqlFragment.Accept(visitor); | |
Console.WriteLine("Done."); | |
Console.ReadKey(); | |
} | |
} | |
class OwnVisitor : TSqlFragmentVisitor | |
{ | |
public override void ExplicitVisit(SelectStatement node) | |
{ | |
QuerySpecification querySpecification = node.QueryExpression as QuerySpecification; | |
FromClause fromClause = querySpecification.FromClause; | |
// There could be more than one TableReference! | |
// TableReference is not sure to be a NamedTableReference, could be as example a QueryDerivedTable | |
NamedTableReference namedTableReference = fromClause.TableReferences[0] as NamedTableReference; | |
TableReferenceWithAlias tableReferenceWithAlias = fromClause.TableReferences[0] as TableReferenceWithAlias; | |
string baseIdentifier = namedTableReference?.SchemaObject.BaseIdentifier?.Value; | |
string schemaIdentifier = namedTableReference?.SchemaObject.SchemaIdentifier?.Value; | |
string databaseIdentifier = namedTableReference?.SchemaObject.DatabaseIdentifier?.Value; | |
string serverIdentifier = namedTableReference?.SchemaObject.ServerIdentifier?.Value; | |
string alias = tableReferenceWithAlias.Alias?.Value; | |
Console.WriteLine("From:"); | |
Console.WriteLine($" {"Server:",-10} {serverIdentifier}"); | |
Console.WriteLine($" {"Database:",-10} {databaseIdentifier}"); | |
Console.WriteLine($" {"Schema:",-10} {schemaIdentifier}"); | |
Console.WriteLine($" {"Table:",-10} {baseIdentifier}"); | |
Console.WriteLine($" {"Alias:",-10} {alias}"); | |
// Example of changing the alias: | |
//(fromClause.TableReferences[0] as NamedTableReference).Alias = new Identifier() { Value = baseIdentifier[0].ToString() }; | |
Console.WriteLine("Statement:"); | |
Console.WriteLine(node.ToSqlString().Indent(2)); | |
Console.WriteLine("¯".Multiply(40)); | |
base.ExplicitVisit(node); | |
} | |
} | |
public static class TSqlDomHelpers | |
{ | |
public static string ToSourceSqlString(this TSqlFragment fragment) | |
{ | |
StringBuilder sqlText = new StringBuilder(); | |
for (int i = fragment.FirstTokenIndex; i <= fragment.LastTokenIndex; i++) | |
{ | |
sqlText.Append(fragment.ScriptTokenStream[i].Text); | |
} | |
return sqlText.ToString(); | |
} | |
public static string ToSqlString(this TSqlFragment fragment) | |
{ | |
SqlScriptGenerator generator = new Sql120ScriptGenerator(); | |
string sql; | |
generator.GenerateScript(fragment, out sql); | |
return sql; | |
} | |
} | |
public static class StringHelpers | |
{ | |
public static string Indent(this string Source, int NumberOfSpaces) | |
{ | |
string indent = new string (' ', NumberOfSpaces); | |
return indent + Source.Replace("\n", "\n" + indent); | |
} | |
public static string Multiply(this string Source, int Multiplier) | |
{ | |
StringBuilder stringBuilder = new StringBuilder(Multiplier * Source.Length); | |
for (int i = 0; i < Multiplier; i++) | |
{ | |
stringBuilder.Append(Source); | |
} | |
return stringBuilder.ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment