如何确定任意一块T-SQL所需的参数?

基本上,我正在寻找一个适用于任意T-SQL的SqlCommandBuilder.DeriveParameters

例如,此查询需要一个参数:

 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 

这解释了它如何确定列,但它可能只是字符串解析来获取参数…

您可以使用Microsoft.Data.Schema.ScriptDom 。 我自己并不熟悉,但我只是尝试解析你的语句,并且可以看到变量可以在ScriptTokenStream集合中访问(不确定是否有更简单的方法来获取它们)

编辑:从评论中发布OP自己的代码!

  var sql = "SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz]"; var p = new TSql100Parser(true); var errors = new List(); 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 ,它与相关但是失败,因为它需要能够推导出数据类型。

使用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(); } } 

我认为SqlCommandBuilder.DeriveParameters工作原理是询问SQL Server参数是什么,在这种情况下不是一个选项。 像RegEx这样的字符串处理可能是你最好的选择。

这个正则表达式也许能够做到这一点

 @([_a-zA-Z]+) 

没有自己试过,但它来自这个类似的问题

它还会在注释和引用的字符串中找到参数,但它是一个开始。