Tsql 内联T-SQL或子查询

Tsql 内联T-SQL或子查询,tsql,ado.net,Tsql,Ado.net,试图找出在内联SQL语句中使用子查询的最有效方法。内联SQL不是我有很多经验的东西,但我在我的组织中没有选择 SELECT * FROM dbo.VW_RMISPayment WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019' AND Status = 'P' AND Fund = '359' AND Amount > 0 AND (BatchNotate = 'B' OR BatchNotate IS NULL) O

试图找出在内联SQL语句中使用子查询的最有效方法。内联SQL不是我有很多经验的东西,但我在我的组织中没有选择

SELECT * 
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019' 
  AND Status = 'P' 
  AND Fund = '359' 
  AND Amount > 0 
  AND (BatchNotate = 'B' OR BatchNotate IS NULL)
ORDER BY ProcDate, Amount
如何参数化BatchNotate='B'或BatchNotate为空部分

我的变量作为列表传入,但我可以将其更改为任何内容。我只是不确定如何从变量创建这个子查询

if (BatchNotate.Count() > 0)
{
    query += " AND BatchNotate= @BatchNotate";
}

 cmd.Parameters.AddWithValue("@BatchNotate", batchNotate);

你能这样做吗

SELECT * 
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019' 
  AND Status = 'P' 
  AND Fund = '359' 
  AND Amount > 0 
  AND BatchNotate = COALESCE(@BatchNotate, BatchNotate)
ORDER BY ProcDate, Amount
使用以下命令:

BatchNotate = COALESCE(@inVariable,'B')
如果变量@conversale为null,则默认为B


如果它是其他东西,它将与之相比。

这两个都不是我想要的东西。这就是我最后要做的。这有点老套,但很管用

 public static string AddParametersOR<T>(SqlParameterCollection parameters,
                                string fieldName,
                                string pattern,
                                SqlDbType parameterType,
                                int length,
                                IEnumerable<T> values)
{
    if (parameters == null)
        throw new ArgumentNullException("parameters");
    if (pattern == null)
        throw new ArgumentNullException("pattern");
    if (values == null)
        throw new ArgumentNullException("values");
    if (!pattern.StartsWith("@", StringComparison.CurrentCultureIgnoreCase))
        throw new ArgumentException("Pattern must start with '@'");

    var parameterNames = new List<string>();
    foreach (var item in values)
    {
        var parameterName = parameterNames.Count.ToString(pattern, CultureInfo.InvariantCulture);
        string parameterWithFieldName = string.Empty;
        if (item.ToString().ToUpper() == "NULL")
        {
            parameterWithFieldName = string.Format("{0} IS NULL", fieldName);
        }
        else if (item.ToString().ToUpper() == "NOTNULL")
        {
            parameterWithFieldName = string.Format("{0} IS NOT", fieldName);
        }
        else
        {
            parameterWithFieldName = string.Format("{0}= {1}", fieldName, parameterName);
        }
        parameterNames.Add(parameterWithFieldName);
        parameters.Add(parameterName, parameterType, length).Value = item;
    }

    return string.Join(" OR ", parameterNames.ToArray());
}
根据列表中的项目数量,输出将如下所示:

BatchNotate='B'或BatchNotate='N'或BatchNotate为空


如果发现NULL或NOTNULL,它将用IS NULL或IS NOT NULL替换它们

此解决方案适合SQL注入攻击请进一步解释原因???AddParameters将param限制为Varchar1-因此,如果在字段名设置为1=1的情况下调用,则将使用1个字符进行攻击?当然;删除表dbo.VW\u RMISPayment;-项目设置为null或NOTNULL我可以看出fieldName是以编程方式设置的,最终用户无法访问。我质疑-许多注入攻击都是通过更改配置文件等来执行的。你不应该接受任何变量并将其插入到查询中。这对我来说毫无意义COALESCE@BatchNotate,NULL没有任何功能。我编辑了我的答案。这更有意义吗?很可能我没有正确理解这个问题。是的@Isaac修复了这个bug,我不确定OP想要的是什么功能,但至少它是有意义的。您可能需要研究表值参数。然后你可以使用像。。。哪里并且存在从@BatchNotations中选择42作为BN,其中BN.BatchNotate=VW_RMISPayment.BatchNotate或VW_RMISPayment.Batch_Notate为空。。。其中@BatchNotations是一个表值参数,每个要处理的值对应一行。
if (batchNotate.Count() > 0)
 {
    query += " AND ({@BatchNotate})";
 }

string batchNotateParamNames = SqlHelper.AddParametersOR(cmd.Parameters, "BatchNotate", "@B0", SqlDbType.VarChar, 1, batchNotate);

cmd.CommandText = query.Replace("{@BatchNotate}", batchNotateParamNames);