1

I am trying to pass an Array to a method and then return a string I can use for a SQL WHERE clause. I have the following and it works just fine. But is there a better way? I am looking for one of the two results;

  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 + "))";
    }
3
  • 3
    See string.Join and the many duplicates. FWIW: I recommend using (dynamically added) placeholders, as SQL is SQL. Commented Nov 6, 2012 at 21:17
  • 4
    Have you looked into paramaterized queries or other forms of sanitized input? This code is just begging for a sql injection attack. Commented Nov 6, 2012 at 21:18
  • @YYY - Yes, I will be doing a paramaterized query. Just trying to get this to work first. Commented Nov 6, 2012 at 21:45

2 Answers 2

1

As suggested in the comments, string.Join:

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

This assumes there's something in the list, so make sure to throw or return if the filter set is empty.

You might also consider doing some kind of validation on the items to prevent SQL injection:

if (paObjectValues.Any(item => !int.TryParse(item))) 
    throw new Exception("Items must be numeric");
Sign up to request clarification or add additional context in comments.

Comments

1

I would add parameters for every option (allowing query-plan re-use and injection-safety), or I would investigate a "split" UDF. Or, better, I'd use something like an ORM or micro-ORM which may often have this type of capability built in. For example, with LINQ you can often use an array/list and Contains. Or with "dapper" you can use a subtle variant of the IN syntax which expands the inputs into separate parameters - specifically: where x.Foo in @bar becomes where x,Foo in (@bar0, @bar1, @bar2) if the "bar" parameter has 3 values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.