0

我找不到如何将IN运算符与SqlParameteronvarchar列一起使用。请查看以下@Mailbox参数:

using (SqlCommand command = new SqlCommand())
{
    string sql =
    @"select    
         ei.ID as InteractionID,
         eo.Sentdate as MailRepliedDate
      from    
         bla bla
      where  
         Mailbox IN (@Mailbox)";
    command.CommandText = sql;
    command.Connection = conn;
    command.CommandType = CommandType.Text;                    
    command.Parameters.Add(new SqlParameter("@Mailbox", mailbox));                    
    SqlDataReader reader = command.ExecuteReader();
}

我尝试了这些字符串,但查询不起作用。

string mailbox = "'abc@abc.com','def@def.com'"
string mailbox = "abc@abc.com,def@def.com"

我也尝试过更改查询Mailbox IN('@Mailbox')
string mailbox = "abc@abc.com,def@def.com"

有什么建议么?谢谢

4

3 回答 3

2

这种方式行不通。

IN您可以在子句中参数化列表中的每个值:

string sql =
  @"select    
         ei.ID as InteractionID,
         eo.Sentdate as MailRepliedDate
      from    
         bla bla
      where  
         Mailbox IN ({0})";
string mailbox = "abc@abc.com,def@def.com";
string[] mails = mailbox.Split(',');
string[] paramNames = mails.Select((s, i) => "@tag" + i.ToString()).ToArray();
string inClause = string.Join(",", paramNames);

using (var conn = new SqlConnection("ConnectionString"))
using (SqlCommand command = new SqlCommand(sql, conn))
{
    for (int i = 0; i < paramNames.Length; i++)
    {
        command.Parameters.AddWithValue(paramNames[i], mails[i]);
    }
    conn.Open();
    using (SqlDataReader reader = command.ExecuteReader())
    { 
        // ...
    }
}

改编自:https ://stackoverflow.com/a/337792/284240

于 2014-03-06T10:02:57.053 回答
0

由于您使用的是 MS SQL 服务器,因此您有 4 个选择,具体取决于版本。按优先顺序列出。

1. 传递一个复合值,并调用一个自定义的 CLR 或表值函数将其分解为一个集合。看这里

您需要编写自定义函数并在查询中调用它。您还需要将该程序集加载到您的数据库中,以使 CLR 可作为 TSQL 访问。

如果您阅读了上面链接的所有Sommarskog 的工作,并且我建议您阅读,您会发现如果性能和并发性真的很重要,您可能需要实现一个 CLR 函数来完成这项任务。有关一种可能实现的详细信息,请参见下文。

2. 使用表值参数。看这里

您需要最新版本的 MSSQL 服务器。

3. 传递多个参数。

您必须在语句中动态生成正确数量的参数。蒂姆施梅尔特的回答显示了一种方法来做到这一点。

4、在客户端生成动态SQL。我不建议你真的这样做。

您必须小心避免注入攻击,并且从查询计划重用中受益的机会较小。

不要这样做


一种可能的 CLR 实现。

using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public class CLR_adam
{
    [Microsoft.SqlServer.Server.SqlFunction(
       FillRowMethodName = "FillRow_char")
    ]
    public static IEnumerator CLR_charlist_adam(
      [SqlFacet(MaxSize = -1)]
      SqlChars Input,
      [SqlFacet(MaxSize = 255)]
      SqlChars Delimiter
       )
    {
        return (
            (Input.IsNull || Delimiter.IsNull) ?
            new SplitStringMulti(new char[0], new char[0]) :
            new SplitStringMulti(Input.Value, Delimiter.Value));
    }

    public static void FillRow_char(object obj, out SqlString item)
    {
        item = new SqlString((string)obj);
    }

    [Microsoft.SqlServer.Server.SqlFunction(
       FillRowMethodName = "FillRow_int")
    ]
    public static IEnumerator CLR_intlist_adam(
      [SqlFacet(MaxSize = -1)]
      SqlChars Input,
      [SqlFacet(MaxSize = 255)]
      SqlChars Delimiter
       )
    {
        return (
            (Input.IsNull || Delimiter.IsNull) ?
            new SplitStringMulti(new char[0], new char[0]) :
            new SplitStringMulti(Input.Value, Delimiter.Value));
    }

    public static void FillRow_int(object obj, out int item)
    {
        item = System.Convert.ToInt32((string) obj);
    }


    public class SplitStringMulti : IEnumerator
    {
        public SplitStringMulti(char[] TheString, char[] Delimiter)
        {
            theString = TheString;
            stringLen = TheString.Length;
            delimiter = Delimiter;
            delimiterLen = (byte)(Delimiter.Length);
            isSingleCharDelim = (delimiterLen == 1);

            lastPos = 0;
            nextPos = delimiterLen * -1;
        }

        #region IEnumerator Members

        public object Current
        {
            get
            {
                return new string(
                    theString,
                    lastPos,
                    nextPos - lastPos).Trim();
            }
        }

        public bool MoveNext()
        {
            if (nextPos >= stringLen)
                return false;
            else
            {
                lastPos = nextPos + delimiterLen;

                for (int i = lastPos; i < stringLen; i++)
                {
                    bool matches = true;

                    //Optimize for single-character delimiters
                    if (isSingleCharDelim)
                    {
                        if (theString[i] != delimiter[0])
                            matches = false;
                    }
                    else
                    {
                        for (byte j = 0; j < delimiterLen; j++)
                        {
                            if (((i + j) >= stringLen) || 
                                (theString[i + j] != delimiter[j]))
                            {
                                matches = false;
                                break;
                            }
                        }
                    }

                    if (matches)
                    {
                        nextPos = i;

                        //Deal with consecutive delimiters
                        if ((nextPos - lastPos) > 0)
                            return true;
                        else
                        {
                            i += (delimiterLen-1);
                            lastPos += delimiterLen;
                        }
                    }
                }

                lastPos = nextPos + delimiterLen;
                nextPos = stringLen;

                if ((nextPos - lastPos) > 0)
                    return true;
                else
                    return false;
            }
        }

        public void Reset()
        {
            lastPos = 0;
            nextPos = delimiterLen * -1;
        }

        #endregion

        private int lastPos;
        private int nextPos;

        private readonly char[] theString;
        private readonly char[] delimiter;
        private readonly int stringLen;
        private readonly byte delimiterLen;
        private readonly bool isSingleCharDelim;
    }
};
于 2014-03-06T10:35:52.100 回答
-1

为什么不把你的mailbox变量和你的sql字符串变量连接起来

于 2014-03-06T10:01:14.480 回答