在C#中解析SQL代码

79

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

具体地说,是否有任何可以解析SQL代码并生成树或其他结构的免费可用解析器?它还应该能够为嵌套结构生成正确的树形结构。

它还应返回该节点表示的语句类型。

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

或者,是否有任何方法可以在C#中解析代码,并生成所需类型的树形结构?


https://dev59.com/L5Hea4cB1Zd3GeqPtcHI - user423430
8个回答

37

特别针对 Transact-SQL(Microsoft SQL Server),您可以使用 Microsoft.SqlServer.Management.SqlParser.Parser 命名空间,该命名空间可在 Microsoft.SqlServer.Management.SqlParser.dll 中找到。这是一个随 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等常量。
更新:现在它是一个独立的NuGet包:https://www.nuget.org/packages/Microsoft.SqlServer.Management.SqlParser

看起来这是最好的选择。但是我似乎需要手动构建一个表达式树。 - Gqqnbig

12

[警告:截至2021年可能不再适用]

使用微软的Entity Framework(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上查看。

而且一切都在Ballmer的掌控下 :-)

The Code Project 上也有一个,SQL解析器

祝你好运。


28
这需要使用“Entity-SQL”,一种SQL方言;我相信OP的意思是常规的SQL,比如“Transact-SQL”(SQL Server的方言)。简而言之,这不起作用。 - Marc Gravell
据我所知,原始问题中没有任何线索表明方向?因此,在我们排除之前,我们是否应该等待@aaCog确认? - TFD
好的,我指的是SQL而不是T-SQL。 此外,我不想向数据库服务器提交任何命令,只想在你认为是简单文本的SQL代码上进行处理。 - Archie
25
我无法在 MSDN 上找到 EntityCommand 的 Expression 属性。http://msdn.microsoft.com/en-us/library/system.data.entityclient.entitycommand.aspx - burnt1ce
14
针对消极者。这个答案在2009年是有效的。基金会已经发展了,现在不再适用。 - TFD
6
这个回答不再正确这一事实是下投票的一个合理原因。你知道,这就是Stackoverflow的工作方式。它依赖于人们更新答案,或者接受它将被投票降低,以便更正确的答案被投票排名靠前。 - PaulG

12

2
由于CodePlex即将关闭,这里提供更新的链接:https://github.com/IronyProject/Irony - Jan 'splite' K.

8
您可以查看一个商业组件:通用SQL解析器,网址为http://www.sqlparser.com。它支持Oracle、T-SQL、DB2和MySQL的SQL语法。

生成内部查询解析树,以XML输出以进行进一步处理。支持嵌套子查询、复杂联接和存储过程中的语句。http://www.dpriver.com/blog/list-of-demos-illustrate-how-to-use-general-sql-parser/generate-internal-query-parse-tree-in-xml-for-further-processing/ - James
是的,我正在使用它,API 有点令人困惑,但绝对能完成工作。价格也相当合理。支持非常有帮助。 - tbone

6

尝试使用 ANTLR - 那里面有很多SQL语法。


1
有没有使用AntLR的.NET示例应用程序-如果可能的话,附带源代码? - Kiquenet
@PuterdoBorato 的链接好像失效了 :( - Chris Owens
@Chris 我使用Antler 4.5.3生成了一些SQL解析器。然而,这个东西似乎无法编译。已编译的解析器: https://github.com/another-guy/SqlSchemer/tree/0374cf63c1143e2b120b698d78e79bef970ee37e/AntlrSqlParsers你可以按照以下步骤自己编译SQL解析器(也许你有更好的运气来解决问题): https://github.com/another-guy/SqlSchemer/issues/2如果你成功了,请告诉我。我仍然需要一个可用的解析器... - Igor Soloydenko

4
VSTS 2008数据库版GDR包含处理SQL解析和脚本生成的程序集,您可以从项目中引用。数据库版使用解析器来解析脚本文件以表示内存中的数据库模型,然后使用脚本生成器从模型生成SQL脚本。我认为您只需要拥有并在项目中引用两个程序集即可。如果您没有数据库版,您可以安装试用版以获取这些程序集,或者可能有其他方法可以在不安装数据库版的情况下获得它们。请查看以下链接:Data Dude:Getting to the Crown Jewels

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

2
尝试使用 GOLD Parser,它是一款强大且易于学习的BNF引擎。您可以搜索已经创建的语法以获取您想要的内容(例如: SQL ANSI 89 Grammar)。
我开始使用这个来解析HQL(NHibernate查询语言,类似于SQL),非常棒。
更新:现在NH开发团队已经使用ANTLR完成了HQL解析(ANTLR更难使用,但据我所知更强大)。

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接