基本上,我正在寻找相当于 SqlCommandBuilder.DeriveParameters
这将适用于任意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
这解释了它如何确定列,但它 可能 只是字符串解析来获取参数...
您可以使用 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
这是相关的但是在这个例子中失败,因为它需要能够推导出数据类型。
使用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]+)
没有自己试过,但它是从这个 类似的问题
它还会在注释和引用的字符串中找到参数,但它是一个开始。