Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确定任意一段T-SQL所需的参数?_C#_.net_Tsql_Reflection - Fatal编程技术网

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