我想知道如何在C#中编写SQL查询,我必须在IN子句中使用多个字符串。
我有一个List ListSessionId,我想在我的IN子句中使用它们。
类似的东西:
foreach (var sessionid in ListSessionId)
{
query = " SELECT OM.ORDERCONFIRMATIONID AS OCN ";
query += " FROM [DGS].[DGSCRM].[LEAD] ";
query += " WHERE ";
query += " SESSIONID in ('" + sessionid + "') ";
}
因为我的查询类似于:
SELECT OM.ORDERCONFIRMATIONID AS OCN
FROM [DGS].[DGSCRM].[LEAD]
WHERE
SESSIONID in ('sessionid1', 'sessionid2', 'sessionid3')
答案 0 :(得分:4)
虽然你可以用字符串.join
解决这个问题,或者只是迭代你的循环来构建IN
子句中括号之间的东西,但它会让你大开SQL注入。
为了避免您必须参数化SQL字符串的输入。我们通过使用sql命令.Parameters
class。
它看起来像:
var query = "SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] SESSIONID in ({0})";
var idParameterList = new List<string>();
var index = 0;
foreach (var sessiond in ListSessionId)
{
var paramName = "@idParam" + index;
sqlCommand.Parameters.AddWithValue(paramName, sessionid);
idParameterList.Add(paramName);
index++;
}
sqlCommand.CommandText = String.Format(query, string.Join(",", idParameterList));
请注意,我完全猜测您的sqlCommand
变量名称,但您可以根据需要进行交换。
有了这个,我们将SQL字符串/命令分成两个块
sql本身。这最终会被提交到类似SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] SESSIONID in (@idParam0, @idParam1, @idParam3, ... @idParamN)
的数据库。数据库获取此sql字符串并将其编译为好像它具有值。它决定了执行路径,只是坐在它等待值在第二部分
参数的值进来。这是我们在循环中构建的列表。 ListSessionId
中的每个值都与一个名为sqlCommand.Parameters
或@idParam0
的新@idParam1
配对。
因为编译的SQL没有ListSessionID
中的任何实际内容,所以无法在数据库中显示错误的SQL并执行。它已编译并准备执行。因此,当参数命中时,它会运行sql语句和barfs返回结果的计划。很干净。
答案 1 :(得分:3)
您可以使用Linq解决此问题,并使用对确保您的代码安全免受Sql Injection攻击至关重要的参数。使用参数时,请务必同时指定参数类型和长度(如果适用)。我估计长度为100且类型为VarChar
,您可以根据需要进行调整。
// create the parameters
var parameters = ListSessionId.Select((sessionId, indx) => new SqlParameter("@session_" + indx, SqlDbType.VarChar, 100) {Value = sessionId}).ToArray();
// create the query
command.CommandText = $"SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] WHERE SESSIONID IN ({string.Join(",", parameters.Select(x=>x.ParameterName))})";
// add parameters to the command
sqlCommand.Parameters.AddRange(parameters);