在C#中解析SQL代码


71

我想使用C#解析SQL代码。

具体来说,是否有任何免费的解析器可以解析SQL代码并从中生成树或任何其他结构?它还应为嵌套结构生成适当的树。

它还应该返回该树的节点代表哪种语句。

例如,如果节点包含循环条件,则它应返回这是节点的“循环类型”。

还是有什么方法可以解析C#中的代码并生成我想要的类型的树?


Answers:


10

使用Microsoft实体框架(EF)。

它具有一个“ Entity SQL”解析器,该解析器可构建表达式树,

using System.Data.EntityClient;
...
EntityConnection conn = new EntityConnection(myContext.Connection.ConnectionString);
conn.Open();
EntityCommand cmd = conn.CreateCommand();
cmd.CommandText = @"Select t.MyValue From MyEntities.MyTable As t";
var queryExpression = cmd.Expression;
....
conn.Close();

或类似的东西,请在MSDN上查看。

一切都在鲍尔默斯上打勾:-)

The Code Project上还有一个SQL Parser

祝好运。


27
它使用“ Entity-SQL”(SQL的方言);我认为OP表示常规SQL,例如“ Transact-SQL”(SQL Server的方言)。简而言之; 这行不通。
马克·格雷韦尔

据我所知,这两种方式都没有线索吗?所以在我们解决这个问题之前,我们应该等待@aaCog确认吗?
TFD

24
我在msdn上找不到EntityCommand的Expression属性。msdn.microsoft.com/en-us/library/...
burnt1ce

14
对于-ve'ers。该答案在2009年有效。EF继续前进,并且不再适用
TFD 2015年

6
@TFD-但是,此答案不再正确的事实是拒绝投票的正当理由。如您所知,这就是Stackoverflow的工作方式。它依赖于人们要么更新答案,要么接受将其优先投票给更正确的答案,然后再对其进行投票。
PaulG

25

特别是对于Transact-SQL(Microsoft SQL Server),您可以使用Microsoft.SqlServer.Management.SqlParser.dll中提供Microsoft.SqlServer.Management.SqlParser.Parser命名空间命名空间是SQL Server附带的程序集,可以自由分发。

这是将T-SQL作为字符串解析为令牌序列的示例方法:

IEnumerable<TokenInfo> ParseSql(string sql)
{
    ParseOptions parseOptions = new ParseOptions();
    Scanner scanner = new Scanner(parseOptions);

    int state = 0,
        start,
        end,
        lastTokenEnd = -1,
        token;

    bool isPairMatch, isExecAutoParamHelp;

    List<TokenInfo> tokens = new List<TokenInfo>();

    scanner.SetSource(sql, 0);

    while ((token = scanner.GetNext(ref state, out start, out end, out isPairMatch, out isExecAutoParamHelp)) != (int)Tokens.EOF)
    {
        TokenInfo tokenInfo =
            new TokenInfo()
            {
                Start = start,
                End = end,
                IsPairMatch = isPairMatch,
                IsExecAutoParamHelp = isExecAutoParamHelp,
                Sql = sql.Substring(start, end - start + 1),
                Token = (Tokens)token,
            };

        tokens.Add(tokenInfo);

        lastTokenEnd = end;
    }

    return tokens;
}

请注意,TokenInfo该类只是具有上述属性的简单类。

Tokens 这是枚举:

并包括像常数TOKEN_BEGINTOKEN_COMMITTOKEN_EXISTS等。


看起来是最好的。但是我似乎不得不手动构建一个表达式树。
Gqqnbig


8

您可能会看到一个商业组件:http ://www.sqlparser.com上的常规sql解析器 它支持Oracle,T-SQL,DB2和MySQL的SQL语法。


在xml输出中生成内部查询解析树,以进行进一步处理。支持嵌套子查询,复杂的联接和存储过程中的语句。dpriver.com/blog/…–

是的,我正在使用它,该API有点令人困惑,但绝对可以完成工作。价格也很合理。支持非常有帮助。
2011年

6

尝试ANTLR-那里有一堆SQL语法。


1
.NEt中的任何示例应用程序-如果可能,请使用源代码-使用AntLR?
Kiquenet

@PuterdoBorato链接似乎已死:(
克里斯

@Chris我能够使用Antler 4.5.3和生成一些SQL解析器。这似乎不是可编译的。编译的解析器:github.com/another-guy/SqlSchemer/tree/… 您可以按照以下步骤自行编译SQL解析器(也许您有更多的运气解决问题):github.com/another-guy/SqlSchemer/issues/2 如果您知道,请告诉我。我仍然需要一个能正常工作的解析器...
Igor Soloydenko

4

VSTS 2008 Database Edition GDR包含可处理SQL解析和脚本生成的程序集,您可以从项目中引用这些程序集。Database Edition使用解析器来解析脚本文件以表示数据库的内存模型,然后使用脚本生成器从该模型生成SQL脚本。我认为您的项目中只有两个程序集需要引用。如果您没有数据库版本,则可以安装试用版来获取程序集,或者可以通过另一种方式来安装它们而无需安装数据库版本。查看以下链接。 数据花花公子:进入王室珠宝


Mehmet,VSTS 2008数据库版GDR管理Oracle的Sql解析?
Kiquenet

2

尝试使用GOLD Parser,它是功能强大且易于学习的BNF引擎。您可以搜索所需的语法(即:SQL ANSI 89语法)。

我开始将其用于HQL解析(NHibernate查询语言,与SQL非常相似),它很棒。

更新:现在,NH开发团队已使用ANTLR(较难使用,但功能更强大的AFAIK)完成了HQL解析。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.