C# 如何确定任意一段T-SQL所需的参数?
基本上,我正在寻找一个等价于C# 如何确定任意一段T-SQL所需的参数?,c#,.net,tsql,reflection,C#,.net,Tsql,Reflection,基本上,我正在寻找一个等价于SqlCommandBuilder.DeriveParameters的工具,它可以用于任意T-SQL 例如,此查询需要一个参数: SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz] 我基本上需要摘录: new[] { "Foo", "Baz" } 从上面。我可以构建一个SQL解析器,但是我有一个到SQL server的开放连接,所以如果可能的话,我更愿意使用现有的选项 编辑: 必须有办法做到这一点,因为SQLServer的Bu
SqlCommandBuilder.DeriveParameters
的工具,它可以用于任意T-SQL
例如,此查询需要一个参数:
SELECT @Foo [Foo], '@Bar' [Bar], @Baz [Baz]
我基本上需要摘录:
new[] { "Foo", "Baz" }
从上面。我可以构建一个SQL解析器,但是我有一个到SQL server的开放连接,所以如果可能的话,我更愿意使用现有的选项
编辑: 必须有办法做到这一点,因为SQLServer的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
这解释了它如何确定列,但可能只是通过字符串解析来获取参数…使用正则表达式并解析参数,我很快测试了这个,因此不确定是否可行,可能需要修改 [^']@([^[,]+) 如果需要修改正则表达式字符串,我发现此网站非常有用:
public Form1()
{
初始化组件();
string query=“选择@Foo[Foo]、'@Bar'[Bar]、@Baz[Baz]”;
正则表达式r=新正则表达式(@“[^']@([^\[,]+)”);
MatchCollection集合=r.Matches(查询);
string[]数组=新字符串[collection.Count];
for(int i=0;i
我认为SqlCommandBuilder.DeriveParameters
的工作原理是询问SQL Server参数是什么,这在本例中不是一个选项。类似正则表达式的某种字符串处理可能是最好的选择
这个正则表达式可能可以做到这一点
@([_a-zA-Z]+)
我自己也没试过,但就是从这个开始的
它还可以在注释和带引号的字符串中找到参数,但这只是一个开始。您可以使用它。我自己并不熟悉它,但我只是尝试解析您的语句,可以看到变量可以在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();
}
var sql=“选择@Foo[Foo]、'@Bar'[Bar]、@Baz[Baz]”;
var p=新的TSql100Parser(true);
var errors=新列表();
var tokens=p.GetTokenStream(新的StringReader(sql),错误);
如果(errors.Count==0)
{
var变量=(来自令牌中的t,其中t.TokenType==
变量select t.Text).ToArray();
}
SQL Server 2012还引入了与此示例相关但失败的功能,因为它需要能够推断数据类型。您是如何构建此初始字符串的?您可以使用哪些功能来动态构建此字符串以找到所需的参数?如果您在让Business Intelligence Development Studio执行此操作时,请检查服务器?会告诉我们这是一个服务器函数还是字符串parsing您知道吗?@Martin;OMG!我想这正是我需要的。请将此作为答案发布。@Martin:发布此代码:`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=(从令牌中的t开始,其中t.TokenType==TSqlTokenType.Variable选择t.Text)。ToArray();}`我如何使用它来获取SQL查询中的表。我尝试在代码中用表替换变量。它不起作用。当我使用标识符时,它同时提供列名和表名。有没有办法只获取表名?@DeepanCool Gert Draper在这里的回答似乎可以做到这一点
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();
}