我找不到如何在IN
列上使用SqlParameter
运算符和varchar
。请查看以下@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"
有什么建议吗?感谢
答案 0 :(得分: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())
{
// ...
}
}
答案 1 :(得分:0)
由于您使用的是MS SQL服务器,因此您有4种选择,具体取决于版本。按优先顺序列出。
<强> 1。传递复合值,并调用自定义CLR或表值函数将其分解为集合。 see here 强>
您需要编写自定义函数并在查询中调用它。您还需要将该程序集加载到您的数据库中,以使CLR可以作为TSQL访问。
如果您阅读了上面链接的所有Sommarskog's work,并且我建议您这样做,您会看到如果性能和并发性非常重要,您可能希望实现CLR功能来执行此任务。有关one possible implementation的详细信息,请参阅下文。
<强> 2。使用表值参数。 see here 强>
您需要最新版本的MSSQL服务器。
第3。传递多个参数。
您必须在语句中动态生成正确数量的参数。 Tim Schmelter's answer显示了实现此目的的方法。
<强> 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;
}
};
答案 2 :(得分:-1)
为什么不将mailbox
变量与sql
字符串变量重新同步