用反讽解析SQL语句

我正在尝试创建一个将常规sql语句转换为c#对象的方法,所以我决定使用Irony来解析sql语句然后我将该语句作为Action返回,其中包含语句的类型及其值取决于类型

这是我未完成的代码[因为我感到很沮丧因为我不知道该怎么做]

private List ParseStatement(string statement) { var parser = new Parser(new SqlGrammar()); var parsed = parser.Parse(statement); var status = parsed.Status; while (parsed.Status == ParseTreeStatus.Parsing) { Task.Yield(); } if (status == ParseTreeStatus.Error) throw new ArgumentException("The statement cannot be parsed."); ParseTreeNode parsedStmt = parsed.Root.ChildNodes[0]; switch (parsedStmt.Term.Name) { case "insertStmt": var table = parsedStmt.ChildNodes.Find(x => x.Term.Name == "Id").ChildNodes[0].Token.ValueString; var valuesCount = parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find( x => x.Term.Name == "exprList").ChildNodes.Count; var values = parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find( x => x.Term.Name == "exprList").ChildNodes; foreach (var value in values) { string type = value.Token.Terminal.Name; } break; } return null; } private Type ParseType(string type) { switch (type) { case "number": return typeof (int); case "string": return typeof (string); } return null; } 

所以这里的问题是:我如何利用Irony将字符串SQL语句转换为ac#对象?

这是我想要实现的一个例子:

插入人物价值(4,’Nilsen’,’Johan’,’Bakken 2’,’Stavanger’)

并将其转换为

 return new Action; 

动态地取决于方法从语句中读取的内容。

我希望我已经很好地解释了我的想法,所以你可以帮助我们,如果有什么不清楚请告诉我,我会尝试解释它。

我也试图用Irony解析SQL。 我放弃了,因为Irony中的示例SQL解析器不处理:CTE,按列号排序,一半特殊语句之类的

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

虽然我很开心学习Irony,但我没有正确的编码方法来实现上述所有部分。

我最终使用了Microsoft提供的SQL解析库。 以下LINQPad 5的示例代码:

 // Add a reference to // C:\Program Files (x86)\Microsoft SQL Server\130\SDK\Assemblies\ // Microsoft.SqlServer.TransactSql.ScriptDom.dll // // https://blogs.msdn.microsoft.com/gertd/2008/08/21/getting-to-the-crown-jewels/ public void Main() { var sqlFilePath = @"C:\Users\Colin\Documents\Vonigo\database-scripts\Client\Estimate\spClient_EstimateAddNew.sql"; bool fQuotedIdenfifiers = false; var parser = new TSql100Parser(fQuotedIdenfifiers); string inputScript = File.ReadAllText(sqlFilePath); IList errors; using (StringReader sr = new StringReader(inputScript)) { var fragment = parser.Parse(sr, out errors); fragment.Dump(); } } 

如果您不是这样做的有趣练习,我建议使用Linq to SQL生成存根类或Entity Framework作为注释中提到的Drunken Code Monkey。

这是一篇很好的文章,可以帮助您入门: 从现有数据库生成EF代码