WebService执行SQL无参数传入时出现语法错误的问题排查
问题分析与解决方案
首先,你的报错根源在于直接将Nullable类型变量拼接进SQL语句,当vSagsNr未传入(即值为null)时,C#会把null字符串拼接为空,导致生成的SQL出现语法错误。比如这段代码:
"where TekstWeb like '%Oven%' and " + vSagsNr + " IS NULL OR u.SagsNr = " + vSagsNr
当vSagsNr为null时,拼接后的SQL片段会变成:
where TekstWeb like '%Oven%' and IS NULL OR u.SagsNr =
这显然违反了SQL语法,数据库自然会抛出"Incorrect syntax near the keyword 'IS'"的错误。
正确的做法:使用参数化查询
直接拼接SQL字符串不仅会导致这类语法问题,还存在严重的SQL注入风险,参数化查询是解决这类问题的标准方案,同时能完美处理null值的传递。
修改后的C#代码如下:
using (SqlConnection con = Database()) // 使用using自动释放连接,避免资源泄漏 { // 编写带参数的SQL语句,和你在SSMS中运行的版本一致 string sql = @"select u.SagsNr, uf.TekstWeb from UdlejningsSagFacilitet uf inner join UdlejningsSag u on uf.UdlejningsSagId = u.UdlejningsSagId where u.VisesPaaNettet = 1 and exists( select * from UdlejningsSagFacilitet uf inner join UdlejningsSag u on uf.UdlejningsSagId = u.UdlejningsSagId where TekstWeb like '%Oven%' and (@param IS NULL OR u.SagsNr = @param) ) and (@param IS NULL OR u.SagsNr = @param)"; SqlCommand cmd = new SqlCommand(sql, con); // 添加参数,自动处理null值 cmd.Parameters.Add("@param", SqlDbType.Int).Value = vSagsNr.HasValue ? (object)vSagsNr.Value : DBNull.Value; SqlDataAdapter daf = new SqlDataAdapter(cmd); DataTable dtf = new DataTable(); daf.Fill(dtf); string jsonf = GetJson(dtf); return jsonf; }
额外提醒:SQL逻辑的优先级问题
注意你原SQL中的AND和OR优先级,默认AND比OR优先级高。你当前的where子句逻辑相当于:
(u.VisesPaaNettet = 1 and exists(...) and @param IS NULL) OR u.SagsNr = @param
如果这正是你想要的逻辑(即传入参数时忽略前面的条件,直接返回对应SagsNr的记录),那没问题;如果希望传入参数时同时满足u.VisesPaaNettet = 1和exists(...)条件,需要把@param IS NULL OR u.SagsNr = @param用括号包裹起来,和前面的条件用AND连接,就像我上面代码中做的那样。
内容的提问来源于stack exchange,提问作者Der Kejser
相关产品推荐
相关产品推荐

