You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java对接SQL Server时Prepared Statement执行LIKE查询无返回结果如何解决

问题根因

你写的预编译SQL逻辑存在两处核心错误:

  • 预编译语句的占位符?仅支持传入值参数,不支持传入字段名、表名这类SQL标识符。你给第一个?传入字段名property的操作,实际执行时会被数据库当做字符串常量处理,等于执行的是where '字段名的字符串内容' like '匹配值',自然不会返回符合预期的结果。
  • LIKE匹配的参数不需要手动加单引号,setString方法会自动处理字符串的转义和边界包裹逻辑,你手动加单引号会导致单引号被识别为匹配值的一部分,和你实际要匹配的内容不符。

解决方案

字段名无法通过预编译占位符传入,因此需要做白名单校验后拼接,匹配值继续用预编译占位符传入,既保证安全性又能正常执行查询,修正后的代码如下:

List<Guest> guestList = new ArrayList<>();
// 第一步:做查询字段白名单校验,防止SQL注入,替换为你业务中实际允许查询的字段
List<String> allowedQueryProperties = Arrays.asList("guest_name", "contact_phone", "email");
if (!allowedQueryProperties.contains(property)) {
    throw new IllegalArgumentException("非法的查询字段参数");
}
// 第二步:拼接经过校验的字段名,LIKE匹配值用预编译占位符
String query = "select * from Guests where " + property + " like ?";
PreparedStatement preparedStatement = connection.prepareStatement(query);
// 第三步:给占位符赋值,仅加%通配符即可,无需手动加单引号
preparedStatement.setString(1, "%" + value + "%");

ResultSet resultSet = preparedStatement.executeQuery();
guestList = getGuestListFromResultSet(resultSet);
return guestList;

补充说明

字段名的白名单校验是必须环节,只有经过校验的字段名拼接后才是安全的,配合值参数的预编译处理,整体方案可以完全规避SQL注入风险。

内容的提问来源于stack exchange,提问作者stefanp99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:54:06