Разбор SQL-заявления с помощью иронии

Я пытаюсь создать метод, который преобразует регулярный оператор sql в объекты С#. Поэтому я решил использовать Ирони для анализа оператора 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 Statement в объекты С#?

Вот пример того, чего я хочу достичь:

ВСТАВЬТЕ ЧЕЛОВЕК (4, "Нильсен", "Йохан", "Бакен 2", 'Ставангера')

И преобразуйте его в

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

Динамически зависит от того, что метод прочитал из инструкции.

Надеюсь, я хорошо объяснил свою идею, чтобы вы могли помочь мне, ребята, и если есть что-то непонятное, скажите мне, и я попытаюсь объяснить это.

Ответ 1

Если вы не делаете это как забавное упражнение, я бы рекомендовал использовать Linq to SQL для создания ваших классов-заглушек или Entity Framework в качестве пьяной кодовой обезьяны, упомянутых в комментариях.

Вот вам хорошая статья, чтобы вы начали: Создание кода EF из существующей базы данных

Ответ 2

Я тоже пытался разбирать SQL с Иронией. Я отказался, потому что образец SQL-анализатора в Irony не обрабатывает: CTEs, Order by column number, половина специальных операторов вроде

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

В то время как я отлично изучил Ирония, у меня нет кодирующих отбивных, чтобы правильно реализовать все вышеупомянутые части.

Я закончил использовать предоставленную 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<ParseError> errors;
    using (StringReader sr = new StringReader(inputScript))
    {
        var fragment = parser.Parse(sr, out errors);
        fragment.Dump();
    }
}