C#中拼接含双IN子句(OR连接)的SQL时出现')'语法错误求助
问题排查与修复方案
首先咱们来拆解一下你遇到的语法错误根源:
你的第一个for循环结束后,变量i的值已经等于brandsList.Length了(因为循环条件是i < brandsList.Length,最后一次循环执行完i++后,i就会等于数组长度)。这时候第二个循环的起始值是j = i + 1,也就是brandsList.Length + 1,这显然大于brandsList.Length,导致第二个循环完全没有执行。
最终生成的SQL语句会变成这样:
SELECT * FROM tbl_VSArticle WHERE Brand1 in (@0, @1, ...) OR Brand2 in ()
数据库看到Brand2 in ()这种写法肯定会报错,因为IN关键字后面必须跟非空的参数列表或者合法子查询。
修复方案
根据不同的业务需求,这里提供两种常见的修复方式:
需求1:同一个品牌列表同时匹配Brand1或Brand2
如果是希望品牌列表里的任意值匹配Brand1或者Brand2,那需要让两个IN子句都使用完整的品牌列表,同时要注意参数名不能重复(避免参数覆盖):
var cmd = new SqlCommand(); var sql = new System.Text.StringBuilder(); sql.Append("SELECT * FROM tbl_VSArticle WHERE "); // 处理Brand1的IN子句 sql.Append("Brand1 in ("); for (int i = 0; i < brandsList.Length; i++) { string paramName = $"@Brand1_{i}"; cmd.Parameters.Add(paramName, brandsList[i]); if (i > 0) sql.Append(", "); sql.Append(paramName); } sql.Append(") OR Brand2 in ("); // 处理Brand2的IN子句,用不同前缀区分参数名 for (int j = 0; j < brandsList.Length; j++) { string paramName = $"@Brand2_{j}"; cmd.Parameters.Add(paramName, brandsList[j]); if (j > 0) sql.Append(", "); sql.Append(paramName); } sql.Append(")");
需求2:品牌列表拆分给Brand1和Brand2
如果是想把品牌列表的前半部分匹配Brand1,后半部分匹配Brand2,那需要重新规划循环的索引范围,同时要判断是否有剩余品牌需要处理:
var cmd = new SqlCommand(); var sql = new System.Text.StringBuilder(); sql.Append("SELECT * FROM tbl_VSArticle WHERE "); int halfLength = brandsList.Length / 2; // 处理Brand1的IN子句,取前半部分品牌 sql.Append("Brand1 in ("); for (int i = 0; i < halfLength; i++) { cmd.Parameters.Add($"@Brand1_{i}", brandsList[i]); if (i > 0) sql.Append(", "); sql.Append($"@Brand1_{i}"); } sql.Append(")"); // 只有当品牌数量超过一半时,才添加Brand2的条件 if (brandsList.Length > halfLength) { sql.Append(" OR Brand2 in ("); for (int j = halfLength; j < brandsList.Length; j++) { int paramIndex = j - halfLength; cmd.Parameters.Add($"@Brand2_{paramIndex}", brandsList[j]); if (j > halfLength) sql.Append(", "); sql.Append($"@Brand2_{paramIndex}"); } sql.Append(")"); }
小技巧
以后遇到SQL语法错误时,可以先把生成的SQL语句打印出来(比如Console.WriteLine(sql.ToString())),直观看到最终的SQL结构,排查问题会高效很多。
内容的提问来源于stack exchange,提问作者Taj El Amine
相关产品推荐
相关产品推荐

