Анализ кода SQL в С#

Я хочу проанализировать SQL-код с помощью С#.

В частности, существует ли свободно доступный синтаксический анализатор, который может анализировать SQL-код и генерировать дерево или любую другую структуру из него? Он также должен генерировать правильное дерево для вложенных структур.

Он также должен вернуть какой тип выражения node этого дерева.

Например, если node содержит условие цикла, то он должен вернуть, что это "тип цикла" node.

Или есть способ, которым я могу разобрать код на С# и сгенерировать дерево типа, которое я хочу?

Ответ 1

Используйте 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.

И все это на Ballmers тике :-)

Существует также один из проектов Code, SQL Parser.

Удачи.

Ответ 3

В частности, для Transact-SQL (Microsoft SQL Server) вы можете использовать пространство имен Microsoft.SqlServer.Management.SqlParser.Parser, доступное в Microsoft.SqlServer.Management.SqlParser.dll, сборка, включенная в 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 и т.д.

Ответ 4

Вы можете взглянуть на коммерческий компонент: общий sql-парсер в http://www.sqlparser.com Он поддерживает синтаксис SQL Oracle, T-SQL, DB2 и MySQL.

Ответ 5

Попробуйте ANTLR - Там есть куча грамматических данных SQL.

Ответ 6

VSTS 2008 Database Edition GDR включает сборки, которые обрабатывают разбор SQL и создание script, которые вы можете ссылаться на ваш проект. Database Edition использует синтаксический анализатор для анализа файлов script для представления в памяти модели вашей базы данных, а затем использует генератор script для генерации SQL-скриптов из модели. Я думаю, что есть всего две сборки, которые вам нужны, и ссылку в вашем проекте. Если у вас нет версии базы данных, вы можете установить пробную версию, чтобы получить сборки, или может быть другой способ иметь их без установки версии базы данных. Проверьте следующую ссылку. Данный чувак: добраться до драгоценностей Короны.

Ответ 7

Попробуйте GOLD Parser, это мощный и простой в освоении механизм BNF. Вы можете искать грамматики, уже сделанные для того, что вы хотите (например: SQL ANSI 89 Grammar).

Я начал использовать это для разбора HQL (язык запросов NHibernate, очень похожий на SQL), и это потрясающе.

UPDATE: теперь команда разработчиков NH провела разбор HQL с использованием ANTLR (что сложнее в использовании, но более мощного AFAIK).