1

我试图将一个数组传递给一个方法,然后返回一个可用于 SQL WHERE 子句的字符串。我有以下内容,它工作得很好。但是有更好的方法吗?我正在寻找两个结果之一;

  1. WHERE (ColumnName IN (12, 34, 56, 78, 90))
  2. WHERE (ColumnName IN ('12', '34', '56', '78', '90'))

    public static string setInSearchFilter(string psSearchFilter, string psColumnName, 
        string[] paObjectValues, bool pbIsString)
    {
        string lsDelimiter = "'", lsRetVal = string.Empty, lsObjectValues = string.Empty;

        if (!pbIsString)
        {
            lsDelimiter = string.Empty;
        }

        if (!string.IsNullOrEmpty(psSearchFilter))
        {
            lsRetVal = psSearchFilter + " AND ";
        }

        for (int i = 0; i <= paObjectValues.GetUpperBound(0); i++)
        {
            lsObjectValues += lsDelimiter + paObjectValues[i] + lsDelimiter;

            if (i < paObjectValues.GetUpperBound(0))
            {
                lsObjectValues += ", ";
            }
        }

        return lsRetVal += "(" + psColumnName + " IN (" + lsObjectValues + "))";
    }
4

2 回答 2

1

我会为每个选项添加参数(允许查询计划重用和注入安全),或者我会调查“拆分”UDF。或者,更好的是,我会使用 ORM 或 micro-ORM 之类的东西,它们可能经常内置这种类型的功能。例如,使用 LINQ,您通常可以使用数组/列表和包含。或者使用“dapper”,您可以使用 IN 语法的一个微妙变体,它将输入扩展为单独的参数 - 具体来说:如果“bar”参数具有 3 个值,则where x.Foo in @bar变为。where x,Foo in (@bar0, @bar1, @bar2)

于 2012-11-06T21:25:51.623 回答
1

正如评论中所建议的那样string.Join

string.Format(
    "({0}" + string.Join("{0},{0}", paObjectValues) + "{0})",
    lsDelimiter 
);

这假设列表中有某些内容,因此如果过滤器集为空,请确保抛出或返回。

您还可以考虑对项目进行某种验证以防止 SQL 注入:

if (paObjectValues.Any(item => !int.TryParse(item))) 
    throw new Exception("Items must be numeric");
于 2012-11-06T21:26:28.660 回答