Как я могу определить параметры, необходимые для произвольной части T-SQL? - PullRequest
11 голосов
/ 26 апреля 2011

По сути, я ищу эквивалент SqlCommandBuilder.DeriveParameters, который будет работать для произвольного T-SQL.

Например, для этого запроса требуется один параметр:

SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz]

Iв основном нужно извлечь:

new[] { "Foo", "Baz" }

сверху.Я мог бы создать анализатор SQL, но у меня открытое соединение с сервером SQL, поэтому я предпочел бы использовать существующую опцию, если это возможно.

Редактировать:

Там может иметь способ сделать это, потому что SQL Server Business Intelligence Development Studio может сделать это очень успешно.

Редактировать 2:

SQL BIDS выполняет эту команду для описания результатов:

exec sp_executesql N'SET FMTONLY OFF;SET FMTONLY ON;SELECT @Foo [Foo], ''@Bar'' [Bar], @Baz [Baz]',
    N'@Foo sql_variant,@Baz sql_variant',
    @Foo=NULL,@Baz=NULL

Что объясняет, как он может определять столбцы, но это может быть просто разбором строки для получения параметров ...

Ответы [ 3 ]

10 голосов
/ 26 апреля 2011

Для этого вы можете использовать Microsoft.Data.Schema.ScriptDom . Я сам не знаком с этим, но я просто попытался проанализировать ваше утверждение и увидел, что переменные были доступны в коллекции ScriptTokenStream (не уверен, есть ли более простой способ их получить или нет)

Редактировать: размещение собственного кода ОП из комментариев!

    var sql = "SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz]";
    var p = new TSql100Parser(true);
    var errors = new List<ParseError>();
    var tokens = p.GetTokenStream(new StringReader(sql), errors);
    if (errors.Count == 0)
    {
        var variables = (from t in tokens where t.TokenType == 
                       TSqlTokenType.Variable select t.Text).ToArray();
    }

SQL Server 2012 также вводит sp_describe_undeclared_parameters, который имеет отношение к делу, но не работает в этом примере, так как он должен иметь возможность выводить типы данных.

1 голос
/ 26 апреля 2011

Используйте RegEx и анализируйте параметры, я быстро проверил это, поэтому не уверен, что сработает, возможно, потребуется модификация.

[^ '] @ ([^ [,] +)

Если вам нужно изменить строку регулярного выражения, я считаю этот сайт очень полезным: http://regexlib.com/RETester.aspx

public Form1()
    {
        InitializeComponent();

        string query = "SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz] ";
        Regex r = new Regex(@"[^']@([^\[,]+)");
        MatchCollection collection = r.Matches(query);
        string[] array = new string[collection.Count];

        for (int i = 0; i < collection.Count; i++)
        {
            array[i] = collection[i].Value.Trim();

            // If you want the string[] populated without the "@"
            // array[i] = collection[i].Groups[1].Value.Trim();
        }
    }
0 голосов
/ 26 апреля 2011

Я думаю, SqlCommandBuilder.DeriveParameters работает, спрашивая SQL Server, каковы параметры, что в данном случае не вариант.Лучше всего подойдет обработка строк, например, RegEx.

Это регулярное выражение может быть в состоянии сделать это

@([_a-zA-Z]+) 

Сам не пробовал, но это из этого аналогичный вопрос

Он также найдет параметры в комментариях и строках в кавычках, но это только начало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...