C# 将T-SQL语句解析为令牌

C# 将T-SQL语句解析为令牌,c#,.net,sql-server,tsql,parsing,C#,.net,Sql Server,Tsql,Parsing,您可以看到Ccode语句解析为令牌的效果有多好。例如,以下代码: namespace MyNamespace { class MyClass { public void MyFunction(int arg1) { int var1 = arg1; } } } 解析为: 我想做类似的事情,但用T-SQL语句代替。例如,如果我有以下T-SQL语句: IIF(COALESCE([Col001], [Co

您可以看到Ccode语句解析为令牌的效果有多好。例如,以下代码:

namespace MyNamespace
{
    class MyClass
    {
        public void MyFunction(int arg1)
        {
            int var1 = arg1;
        }
    }
}
解析为:

我想做类似的事情,但用T-SQL语句代替。例如,如果我有以下T-SQL语句:

IIF(COALESCE([Col001], [Col002], [Col003]) > [Col004], [Col005] * [Col006] + ISNULL([Col007], [Col008]), CONCAT(SUBSTRING([Col009], 0, 3), 'sample text', [Col010]))
会给我这样的东西:

IIF, COALESCE, ISNULL, CONCAT, SUBSTRING    - functions 
[Col001], [Col002], ... , [Col010]          - columns 
0, 3, 'sample text'                         - variables
或者如果我有:

ISNULL([Col001], [Col002], [Col003])
有错误的结构:

[The isnull function requires 2 argument(s).] - error
没有任何免费或付费的最新解决方案,使用Microsoft解析器似乎是最好的解决方案。正如我所读到的,我需要使用名称空间,但是没有任何示例,并且我无法以我喜欢的方式拆分T-SQL语句。此外,它似乎只适用于完整的语句,例如,您需要SELECT子句,我只需要将它用于代码片段


我可以使用这个名称空间来实现这一点吗?或者最好开始编写C类来满足我的需要?

我必须在csproj中手动添加引用

Microsoft.SqlServer.Management.SqlParser,版本=12.0.0.0,区域性=neutral,PublicKeyToken=89845dcd8080cc91

取自

取自


注意,该解析器识别一定数量的函数,如IIF、COALESCE等。。。。无法识别的功能只是标记为令牌ID,如列名。

即使您能够使用它,您也会想到,您可能无法将其与应用程序打包在一起,因为它没有此许可证?@xanatos我不确定是否理解您的意思。如果可能的话,我想我可以使用这个名称空间。在搜索期间,我发现了一些T-SQL解析器的付费解决方案,但它们不是SQL Server 2008的最新版本,我使用的是T-SQL Server 2012/2014,我认为xanatos在这方面的观点是正确的。无论如何,我都会使用,或者。至少还有另一个用于解析TSQL的microsoft类:这里有人编写了一个使用itANTLR的库,ASP.NET MVC和许多其他项目都使用它。几个SQL方言已经可用,我不得不承认这是一个有效的例子,即使它不是我要找的。我将尝试编写我的解析器,因为提供的其他解析器对于我的需要来说太复杂了,而具有上述名称空间的解决方案也不能满足它们。@gotqn您必须记住,您建议的解析器不是编译器使用的解析器,而是语法高亮器使用的解析器。。。
<Reference Include="Microsoft.SqlServer.Management.SqlParser, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
string sql = "IIF(COALESCE([Col001], [Col002], [Col003]) > [Col004], [Col005] * [Col006] + ISNULL([Col007], [Col008]), CONCAT(SUBSTRING([Col009], 0, 3), 'sample text', [Col010]))";

var po = new ParseOptions { };
var scanner = new Scanner(po);
scanner.SetSource(sql, 0);

Tokens token;
int state = 0;
int start;
int end;
bool isPairMatch;
bool isExecAutoParamHelp;

while ((token = (Tokens)scanner.GetNext(ref state, out start, out end, out isPairMatch, out isExecAutoParamHelp)) != Tokens.EOF)
{
    string str = sql.Substring(start, end - start + 1);
    Console.WriteLine("{0}: {1}", token, str);
}