简体   繁体   English

如何在C#中为IN子句编写sql查询文本

[英]how to write sql query text for IN clause in C#

I want to know how can I write a sql query in C# where I have to use multiple strings in the IN clause.我想知道如何在 C# 中编写 sql 查询,其中我必须在 IN 子句中使用多个字符串。

I have a List ListSessionId, and I want to use each of them in my IN clause.我有一个 List ListSessionId,我想在我的 IN 子句中使用它们中的每一个。

Something like:类似的东西:

foreach (var sessionid in ListSessionId)
{
    query = " SELECT OM.ORDERCONFIRMATIONID AS OCN ";
    query += " FROM [DGS].[DGSCRM].[LEAD] ";
    query += " WHERE ";
    query += " SESSIONID in ('" + sessionid + "') ";
}

so as my query is something like:所以我的查询是这样的:

SELECT OM.ORDERCONFIRMATIONID AS OCN
FROM [DGS].[DGSCRM].[LEAD]
WHERE
SESSIONID in ('sessionid1', 'sessionid2', 'sessionid3')

While you can solve this with a string .join or just iterating your loop to build the stuff between the parentheses in your IN clause, it will leave you wide open for SQL injection.虽然您可以使用字符串.join解决这个问题,或者只是迭代您的循环来构建IN子句中括号之间的内容,但它会让您对 SQL 注入敞开大门。

To avoid that you MUST parameterize your inputs to the SQL string.为避免这种情况,您必须将您的输入参数化为 SQL 字符串。 We do this by using the sql command .Parameters class.我们通过使用 sql 命令.Parameters类来做到这一点。

It will look something like:它看起来像:

var query = "SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] SESSIONID in ({0})"; 

var idParameterList = new List<string>();
var index = 0;
foreach (var sessionid in ListSessionId)
{
    var paramName = "@idParam" + index;
    sqlCommand.Parameters.AddWithValue(paramName, sessionid);
    idParameterList.Add(paramName);
    index++;
}
sqlCommand.CommandText = String.Format(query, string.Join(",", idParameterList));

Note that I'm totally guessing at your sqlCommand variable name, but you can swap that out as needed.请注意,我完全是在猜测您的sqlCommand变量名称,但您可以根据需要将其换掉。

With this we are splitting our SQL string/command up into two chunks有了这个,我们将我们的 SQL 字符串/命令分成两个块

  1. The sql itself. sql 本身。 This ends up being submitted to the database looking like SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] SESSIONID in (@idParam0, @idParam1, @idParam3, ... @idParamN) .这最终被提交到数据库,看起来像SELECT OM.ORDERCONFIRMATIONID AS OCN FROM [DGS].[DGSCRM].[LEAD] SESSIONID in (@idParam0, @idParam1, @idParam3, ... @idParamN) The database gets this sql string and compiles it as if it had values in it.数据库获取这个 sql 字符串并编译它,就好像它有值一样。 It determines the execution path and just sits on it waiting for the values to come through in the second part它确定执行路径,然后坐在上面等待第二部分中的值通过

  2. The parameter's values come in. This is the list we are building in the loop.参数的值进来了。这是我们在循环中构建的列表。 Each value in your ListSessionId gets paired up with a new sqlCommand.Parameters which takes a name @idParam0 or @idParam1 , etc. ListSessionId每个值都与一个新的sqlCommand.Parameters配对,该参数采用名称@idParam0@idParam1等。

Because your SQL is compiled without any of the actual stuff in your ListSessionID there is no way for bad SQL to show up and get executed in your database.因为您的 SQL 是在ListSessionID没有任何实际内容的情况下编译的,所以无法在您的数据库中显示并执行错误的 SQL。 It's compiled and ready to execute.它已编译并准备好执行。 So when the parameters hit, it runs the plan for the sql statement and barfs back results.所以当参数命中时,它运行sql语句的计划并barfs返回结果。 Nice and clean.漂亮干净。

You can solve this with Linq and using parameters which is critical to ensuring your code is safe from Sql Injection attacks.您可以使用 Linq 并使用参数来解决此问题,这对于确保您的代码免受 Sql 注入攻击至关重要。 When using parameters be sure to also specify the parameter type and the length if applicable.使用参数时,请务必同时指定参数类型和长度(如果适用)。 I guessed at a length of 100 and a type of VarChar , you can adjust this as necessary.我猜长度为 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM