用 C # 解析 SQL 代码

我想用 C # 解析 SQL 代码。

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

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

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

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

106044 次浏览

[警告: 自2021年起,答案可能不再适用]

使用 Microsoft实体架构(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 上查查看。

而这一切都取决于鲍尔默: -)

还有一个代码项目,SQL 语法分析器

祝你好运。

试试 ANTLR-上面有很多 SQL 语法。

尝试 金色解析器,这是一个强大的和容易学习的 BNF 引擎。您可以搜索您想要的已经制作的语法(即: SQL ANSI 89语法)。

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

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

VSTS2008数据库版 GDR 包括处理 SQL 解析和脚本生成的程序集,您可以从项目中引用这些程序集。Database Edition 使用解析器解析脚本文件,以表示数据库的内存模型,然后使用脚本生成器从模型生成 SQL 脚本。我认为只有两个程序集需要在您的项目中使用和引用。如果没有数据库版本,则可以安装试用版来获取程序集,或者可以通过其他方式不安装数据库版本来获取程序集。你可在此查阅以下连结。 数据兄弟: 开始皇冠上的明珠。

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

就像 Diego 建议的那样,恕我直言,语法才是正确的选择。我以前试过 Coco/r,但是对于复杂的 SQL 来说太简单了。ANTLR许多语法都准备好了。

有人甚至试图建立一个 SQL 引擎,检查代码,如果有你在 SharpHSQL-一个用 C # 编写的 SQL 引擎的东西。

Scott Hanselman 最近使用了 有特色的 the 真讽刺,其中包括一个示例 SQL 解析器。

特别是对于 Transact-SQL (Microsoft SQL Server) ,您可以使用 微软。 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等常量。