.NET SqlCommand-在内联查询(Regex?)中查找参数

.NET SqlCommand-在内联查询(Regex?)中查找参数,.net,sql,regex,parameters,.net,Sql,Regex,Parameters,我有一个方法,它使用sp_存储过程列查找存储过程需要发送的所有参数 我的问题是如何对内联SQL查询执行类似的操作 我想获取查询所需的参数列表 实现这一目标的唯一方法是使用正则表达式吗?有什么例子吗? 示例: 我需要获得一个包含@id和@name的列表,我怀疑您必须完全解析SQL。它可能比您预期的更复杂,特别是如果您的SQL不够粗鲁,包含以下内容: 使用命名参数在内部执行存储过程;例如,EXEC MyProc@foo=@localArg——这里查询只需要@localArg 有一个字符串,其中包

我有一个方法,它使用sp_存储过程列查找存储过程需要发送的所有参数

我的问题是如何对内联SQL查询执行类似的操作

我想获取查询所需的参数列表

实现这一目标的唯一方法是使用正则表达式吗?有什么例子吗?


示例:


我需要获得一个包含@id@name

的列表,我怀疑您必须完全解析SQL。它可能比您预期的更复杂,特别是如果您的SQL不够粗鲁,包含以下内容:

  • 使用命名参数在内部执行存储过程;例如,
    EXEC MyProc@foo=@localArg
    ——这里查询只需要
    @localArg
  • 有一个字符串,其中包含
    'some text@foo more text'
    ,可能是由于调用
    sp\u ExecuteSQL
    @foo
    不是查询的一部分)

检查以下代码以获取内联查询中的参数名称:

  Dim SQL As String =  "SELECT * FROM tbl WHERE id = @id AND name = @name"

  Dim arr = SQL.Split(" "c)
  For Each str As String In arr
    If str.StartsWith("@") Then
      MessageBox.Show(str)
    End If
  Next

对于SQL Server提供程序,如果您使用的是存储过程,则可以使用


对于其他情况,我总是发现,如果您的命令至少是常量,那么最好的方法是在VisualStudio中使用设计器支持。创建一个强类型的
数据集
并添加一个查询,或者使用老式的方法将
SqlConnection
SqlCommand
拖到设计图面上。在任何一种情况下,当您将CommandText配置为带有参数的语句时,设计器都会询问您是否需要填写
参数
集合。结果是,它将生成代码来创建一个带有已创建参数集合的SqlCommand。您只需设置参数值,就可以了。

使用RegularExpression的方法也不太难-如果您更喜欢用这种方法查找参数:

   Regex r = new Regex(@"(?<Parameter>@\w*)", RegexOptions.Compiled);

   foreach (Match m in r.Matches(sqlStatement))
   {
      if(m.Success)
      {
         string parameterName = m.Value;
      }
   }
Regex r=newregex(@“(?@\w*)”,RegexOptions.Compiled);
foreach(在r.Matches(sqlStatement)中匹配m)
{
如果(m.成功)
{
字符串参数name=m.值;
}
}
但是,这只会为您提供参数名,它不可能猜测或确定参数类型或任何其他参数元数据,因此最终,这可能是一种快速但可能也是“肮脏”的方法


Marc

我有一个存储过程的解决方案,我使用sp_存储过程列。这应该只是简单内联查询的解决方案。让我们希望“简单查询”不会执行,然后-pSo这真的只是一个正则表达式问题吗?表达式应该是什么?按空间分割不可靠;你可以有“(@foo”,“@foo”,“+@foo”,等等,你是对的,收集所有的大小写并将其放入拆分字符数组并不容易。@也可以合法地作为字符串的一部分出现在SQLWhy is dirty中?我有一个强类型对象,包含所有需要的值,每个成员都有一个描述其DB类型的属性。它听起来脏吗?它真的是一个糟糕的做法?好吧,您只能提取参数的名称,正如Marc Gravell正确地指出的那样,这个简单的正则表达式可能会被简单的边缘情况所愚弄-但是如果它对大多数情况都足够好,请享受!;-)
   Regex r = new Regex(@"(?<Parameter>@\w*)", RegexOptions.Compiled);

   foreach (Match m in r.Matches(sqlStatement))
   {
      if(m.Success)
      {
         string parameterName = m.Value;
      }
   }