2011-04-26 41 views
11

基本上,我正在尋找一個相當於SqlCommandBuilder.DeriveParameters,這將適用於任意T-SQL。如何確定任意一條T-SQL所需的參數?

例如,此查詢需要一個參數:

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

我基本上需要提取:

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

從以上。我可以構建一個SQL解析器,但是我有一個到SQL服務器的開放連接,所以如果可能的話,我寧願使用現有的選項。


編輯:

是一個辦法做到這一點,因爲SQL Server商業智能開發工作室是能夠做到這一點非常成功。


編輯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 

這解釋了它是如何確定列,但可能是隻是字符串解析獲取參數...

+0

你是如何建立這個初始字符串?有什麼你可以使用,你用來動態建立這個字符串來找到所需的參數? – mservidio 2011-04-26 15:35:35

+0

如果您在獲取Business Intelligence Development Studio的同時觀看服務器,SQL Profiler會顯示任何有趣的內容嗎?會告訴我們,如果它是一個服務器功能或只是字符串解析 – AakashM 2011-04-26 15:36:53

+0

也許只是使用正則表達式來查找不引用引號中的@變量...應該工作,我認爲。 – mservidio 2011-04-26 15:38:17

回答

10

您可以使用Microsoft.Data.Schema.ScriptDom。我並不熟悉它,但我只是試着解析你的陳述,並且可以看到這些變量可以在ScriptTokenStream集合中獲得(不確定是否有更容易的方法來獲取它們)

編輯:從評論中發佈OP的自己的代碼!

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這是相關的,但無法與這個例子,因爲它需要能夠推斷出數據類型。

+0

我如何使用它來獲取SQL查詢中的表。我試着用代碼中的表格替換變量。它不工作。當我使用標識符時,它同時提供列名和表名。有沒有辦法只獲取表名? – 2017-01-23 19:59:22

+0

@DeepanCool Gert Draper在這裏的答案看起來像它會這樣做https://social.msdn.microsoft.com/Forums/sqlserver/en-US/24fd8fa5-b1af-44e0-89a2-a278bbf11ae0/parsing?forum=ssdt – 2017-01-23 20:34:32

1

使用正則表達式和解析參數,我很快測試了這個,所以不知道是否會工作,可能需要修改。

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

如果您需要修改的正則表達式字符串,我覺得這個網站非常有幫助: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

我覺得SqlCommandBuilder.DeriveParameters作品通過向SQL Server詢問參數是什麼,在這種情況下這不是一個選項。像RegEx這樣的字符串處理可能是您最好的選擇。

這個表達式可能是能夠做到這一點

@([_a-zA-Z]+) 

還沒有嘗試過自己,但它從這個similar question

它也將找到的評論參數和引用字符串,但它的一個開端。

相關問題