【问题标题】:Parsing T-SQL statements to tokens将 T-SQL 语句解析为标记
【发布时间】:2015-05-26 08:03:49
【问题描述】:

您可以看到hereC#code 语句解析为标记的效果如何。例如以下代码:

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 解析器是最好的解决方案。正如我所读到的,我需要使用 Microsoft.SqlServer.Management.SqlParser.Parser 命名空间,但没有任何示例,我无法以我喜欢的方式拆分 T-SQL 语句。此外,它似乎只适用于完整的语句(例如,您需要 SELECT 子句,而我只需要将它用于代码片段)。

我可以使用这个命名空间来做到这一点,还是最好开始编写 C# 类来满足我的需要?

【问题讨论】:

  • 即使您能够使用它,您也想过您可能无法将它与您的应用“打包”在一起,因为它没有为此获得许可?
  • @xanatos 我不确定我是否理解你。如果可能的话,我想我可以使用这个命名空间。在搜索时,我发现了一些针对 T-SQL 解析器的付费解决方案,但它们不是最新的(使用 SQL Server 2008,我正在使用 SQL Server 2012/2014)
  • 我认为 xanatos 在这里提出了一个有效的观点。无论如何我都会使用ANTLR,或者Irony
  • 至少还有另一个用于解析 TSQL 的“microsoft”类:technet.microsoft.com/en-us/library/… 这里有人sqlblogcasts.com/blogs/sqlandthelike/archive/2012/08/29/… 甚至用它写了一个库
  • ANTLR 被 ASP.NET MVC 和 lot 其他项目使用。几种 SQL 方言已经可用

标签: c# .net sql-server tsql parsing


【解决方案1】:

我不得不在 csproj 中手动添加引用

Microsoft.SqlServer.Management.SqlParser,版本=12.0.0.0,文化=中性,PublicKeyToken=89845dcd8080cc91

喜欢

<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);
}

取自http://www.sqlservercentral.com/blogs/dave_ballantynes_blog/2012/03/13/parsing-t-sql-the-easy-way/

取自Parsing T-SQL – The easy way

请注意,此解析器可识别一定数量的函数(如 IIFCOALESCE、...)。无法识别的函数简单地标记为TOKEN_ID,就像列名一样。

【讨论】:

  • 我不得不承认这是一个可行的例子,即使它不是我想要的。我将尝试编写我的解析器,因为提供的其他解析器对我的需求来说太复杂了,并且上面命名空间的解决方案也不能满足它们。
  • @gotqn 您必须记住,您建议的解析器不是编译器使用的解析器,而是语法高亮器使用的解析器...
猜你喜欢
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 2023-03-04
  • 2020-10-22
相关资源
最近更新 更多