解析SQL语句反讽(Parsing SQL Statement With Irony)

2019-08-17 05:05发布

我试图创建一个普通的SQL语句转换为C#对象的方法,所以我决定用反讽来分析SQL语句,然后我返回语句包含语句的类型和它取决于值的行动类型

这里是我的非完成的代码[因为我很沮丧,因为我不知道该怎么办,然后]

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人员VALUES(4, '尼尔森',约翰 '' 夹爪2 '' 斯塔万格“)

并把它转化为

return new Action<string type, string table, int val1, string val2, string val3, string val4, string val5>;

动态取决于什么方法从宣读的声明。

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

Answer 1:

我试图解析与反讽SQL为好。 我放弃了,因为在反讽样本SQL语法分析程序不处理:热膨胀系数,排序列数,一半的特殊之类的语句

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

虽然我有一个伟大的时间来学习反讽,我没有印章编码正确实现上述所有部件。

我结束了使用微软提供的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();
    }
}


Answer 2:

如果你不这样做,作为一个有趣的练习,我会建议使用LINQ to SQL酒醉代码猴子在评论中提到生成stub类或实体框架。

这里有一个很好的文章,让你开始: 生成EF代码从现有的DB



文章来源: Parsing SQL Statement With Irony
标签: c# sql irony