关于SqlCommand中Like和In参数化无法查询的问题探究

通常我们使用SqlParameter以取代一般的字符串拼接,其目的是:1、防止SQL拼接语法错误(PS:同时防止近视,因为长长的字符串拼接经常把你弄得眼冒金星的……),2、防止SQL注入式攻击(详见:)。

但是并不是所有的SQL都可以直接使用SqlParameter直接替换这样子做那么简单,下面我们来看两个极端例子,顺便分析SqlParameter究竟是什么东西?

1、LIKE+SqlParameter:

假定有这样一句SQL语句:

Select * from xxx where [FieldName] Like @value

如果你是这样做的(省略了其它,关键看@value这部分):

SqlCommand.Parameters.AddWithValue("@value","'你的真实内容'");

这样会导致错误结果的发生——因为SqlParameter针对string类型的会自动在真实的String内容上加上一对单引号。因此你目前执行的SQL就变成了:

Select * from xxx where [FieldName] Like ''你的真实内容''(查询一个带有一对单引号的字符串内容?!)

所以正解是:去掉这一对单引号,改成:

SqlCommand.Parameters.AddWithValue("@value","你的真实内容");

2、IN+SqlParameter:

同理,假定有这样一个SQL查询语句:

Select * from xxx where [FieldName] IN (@value)

如果直接:

SqlCommand.Parameters.AddWithValue("@value","'a,b,c");

会因为前边被加上双引号变成这样的查询语句——

Select * from xxx where [FieldName] IN (''a,b,c'')

所以正确的做法应该是:首先假定传来一个不带引号的字符串"a,b,c",使用String的Split方法按英文逗号分割成若干小串,然后如果是第一个的话前面加半个单引号,末尾一个字符串加半个单引号。其余的加一对,最后再使用String.Join方法拼接,大致关键代码如下:

[C#]

string s = "a,b,c,e,d";
            string[] strings = s.Split(',');
            for (int i = 0; i < strings.Length; i++)
            {
                if (i == 0)
                {
                    strings[i] = strings[i] + "'";
                }
                else if (i == strings.Length - 1)
                {
                    strings[i] = "'" + strings[i];
                }
                else
                {
                    strings[i] = "'" + strings[i] + "'";
                }
            }
string result = String.Join(",",strings);
SqlCommand.Parameters.AddWithValue("@value",result);

[VB.NET]

Dim s As String = "a,b,c,e,d"
Dim strings As String() = s.Split(","C)
For i As Integer = 0 To strings.Length - 1
    If i = 0 Then
        strings(i) = strings(i) & "'"
    ElseIf i = strings.Length - 1 Then
        strings(i) = "'" & strings(i)
    Else
        strings(i) = "'" & strings(i) & "'"
    End If
Next
Dim result As String = [String].Join(",", strings)
SqlCommand.Parameters.AddWithValue("@value", result)
原文地址:https://www.cnblogs.com/ServiceboyNew/p/2561196.html