2009-02-26 48 views
59

我想用C#解析SQL代码。解析C#中的SQL代码#

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

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

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

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

+0

http://stackoverflow.com/questions/34102835 – user423430 2017-01-25 04:15:38

回答

9

使用微软Entity Framework(EF)。

它有一个“实体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上。

而这一切都在Ballmers打勾:-)

也有一个的代码项目,SQL Parser

祝你好运。

+23

即采用SQL的方言“Entity-SQL”;我相信OP意味着常规SQL,例如“Transact-SQL”(SQL Server的方言)。简而言之;这是行不通的。 – 2009-02-26 04:57:38

+0

据我所知,无论哪种方式,在组织问题上都没有线索?因此,在我们解决此问题之前,我们应该等待@aaCog确认? – TFD 2009-02-26 05:05:44

+0

那么,我的意思是SQL而不是T-SQL。 另外,我不想提交任何命令到数据库服务器,但只是想处理SQL代码,你认为这是一个简单的文本。 – Archie 2009-02-26 09:01:27

6

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

2

尝试GOLD Parser,它是一个功能强大且易于学习的BNF引擎。您可以搜索已经为您想要的语法而编写的语法(即:SQL ANSI 89 Grammar)。

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

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

4

VSTS 2008数据库版本GDR包含处理SQL解析和脚本生成的程序集,您可以从项目中引用该程序集。 Database Edition使用解析器解析脚本文件以表示数据库的内存模型,然后使用脚本生成器从模型生成SQL脚本。我认为你的项目中只需要两个程序集并参考。如果您没有数据库版本,则可以安装试用版以获取程序集,也可以通过其他方式在没有安装数据库版本的情况下拥有它们。看看下面的链接。 Data Dude:Getting to the Crown Jewels

8

专供的Transact-SQL(Microsoft SQL Server的),你可以使用the Microsoft.SqlServer.Management.SqlParser.Parser namespace提供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_BEGIN常量,TOKEN_COMMITTOKEN_EXISTS