用反语解析SQL语句
本文关键字:SQL 语句 反语 | 更新日期: 2023-09-27 18:01:24
我正在尝试创建一个将常规sql语句转换为c#对象的方法,所以我决定使用Irony来解析sql语句,然后我将语句返回为包含语句类型的Action,并根据类型
这是我未完成的代码[因为我很沮丧,因为我不知道该怎么做]
private List<Action> 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;
}
所以这里的问题是:我怎么能利用反讽转换字符串SQL语句到c#对象?
下面是我想要实现的一个例子:
然后把它转换成INSERT INTO Persons VALUES (4,'Nilsen', 'Johan', 'Bakken 2',斯塔万格)
return new Action<string type, string table, int val1, string val2, string val3, string val4, string val5>;
动态地取决于方法从语句中读取的内容。
我希望我已经很好地解释了我的想法,所以你们可以帮助我,如果有什么不清楚的,请告诉我,我会尽量解释它
我也试图用Irony来解析SQL。我放弃了,因为Irony中的示例SQL解析器不能处理:cte、按列号排序、一半的特殊语句(如
)。SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
虽然我花了很多时间学习Irony,但我没有正确实现上述所有部分的编码能力。
我最终使用了微软提供的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<ParseError> errors;
using (StringReader sr = new StringReader(inputScript))
{
var fragment = parser.Parse(sr, out errors);
fragment.Dump();
}
}
如果你不这样做作为一个有趣的练习,我建议使用Linq to SQL来生成您的存根类或实体框架,如在评论中提到的醉码猴。
这里有一篇很好的文章可以让你开始:从现有的DB