【发布时间】:2010-10-09 23:59:57
【问题描述】:
我想用 C# 解析 SQL 代码。
具体来说,是否有任何免费可用的解析器可以解析 SQL 代码并从中生成树或任何其他结构?它还应该为嵌套结构生成正确的树。
它还应该返回这棵树的节点代表哪种语句。
例如,如果节点包含一个循环条件,那么它应该返回这是一个节点的“循环类型”。
或者有什么方法可以解析 C# 中的代码并生成我想要的类型的树?
【问题讨论】:
我想用 C# 解析 SQL 代码。
具体来说,是否有任何免费可用的解析器可以解析 SQL 代码并从中生成树或任何其他结构?它还应该为嵌套结构生成正确的树。
它还应该返回这棵树的节点代表哪种语句。
例如,如果节点包含一个循环条件,那么它应该返回这是一个节点的“循环类型”。
或者有什么方法可以解析 C# 中的代码并生成我想要的类型的树?
【问题讨论】:
特别是对于 Transact-SQL (Microsoft SQL Server),您可以使用 Microsoft.SqlServer.Management.SqlParser.dll 中提供的the Microsoft.SqlServer.Management.SqlParser.Parser namespace,这是 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_COMMIT、TOKEN_EXISTS 等常量。
【讨论】:
Scott Hanselman 最近featuredIrony project 包含一个示例 SQL 解析器。
【讨论】:
[警告:自 2021 年起,答案可能不再适用]
使用 Microsoft 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 上查看。
这一切都在鲍尔默打勾:-)
代码项目中也有一个,SQL Parser。
祝你好运。
【讨论】:
你可以看看一个商业组件:general sql parser at http://www.sqlparser.com 支持Oracle、T-SQL、DB2和MySQL的SQL语法。
【讨论】:
试试ANTLR - 上面有一堆 SQL 语法。
【讨论】:
VSTS 2008 数据库版 GDR 包括处理 SQL 解析和脚本生成的程序集,您可以从项目中引用这些程序集。 Database Edition 使用解析器解析脚本文件以表示数据库的内存模型,然后使用脚本生成器从模型生成 SQL 脚本。我认为您的项目中只需要拥有和引用两个程序集。如果您没有数据库版本,您可以安装试用版来获取程序集,或者可能有另一种方法来获得它们而无需安装数据库版本。查看以下链接。 Data Dude:Getting to the Crown Jewels .
【讨论】:
试试GOLD Parser,它是一个功能强大且易于学习的 BNF 引擎。您可以搜索已经创建的语法以获得所需的内容(即:SQL ANSI 89 Grammar)。
我开始将它用于 HQL 解析(NHibernate 查询语言,与 SQL 非常相似),它非常棒。
更新:现在 NH 开发团队已经使用 ANTLR(更难使用,但更强大的 AFAIK)完成了 HQL 解析。
【讨论】:
正如 Diego 所建议的,语法是 IMHO 的必经之路。我之前尝试过 Coco/r,但这对于复杂的 SQL 来说太简单了。 ANTLR 和 a number of grammars 准备好了。
有人甚至尝试构建 SQL 引擎,请检查代码是否有适合您的内容 SharpHSQL - An SQL engine written in C#。
【讨论】: