You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用PreparedStatement拼接变量触发java.sql.SQLException的解决办法

问题分析与修复方案

你的代码触发java.sql.SQLException的核心原因是SQL语法错误,同时对PreparedStatement占位符的使用方式有误。咱们一步步拆解问题,再给出修复方案:

为什么原代码会报错?

你写的SQL语句里,'ADMIN_ ||:1||'是被单引号包裹的完整字符串常量——数据库会把||:1||当成字符串的一部分,而不是识别为拼接运算符和占位符。这就导致两个问题:

  1. 数据库无法解析||的拼接逻辑,直接抛出语法错误;
  2. 就算语法能过,PreparedStatement也找不到对应的占位符(因为:1被包在单引号里,不是有效的占位符标识)。

修复方案(两种可选)

方案1:正确使用管道符(||)拼接(适合Oracle等支持该运算符的数据库)

把常量字符串、拼接运算符、占位符分开写,让数据库能识别拼接逻辑:

// 注意:如果是精确匹配用=,模糊匹配用like并按需加通配符
String query = "SELECT count(*) count from apps.fnd_user fu where UPPER(fu.user_name) = 'ADMIN_' || UPPER(:1)";
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setString(1, companyName); // 也可以在Java层转大写后传入,减少数据库计算

如果需要模糊匹配(比如匹配以ADMIN_+公司名开头的用户),可以调整为:

String query = "SELECT count(*) count from apps.fnd_user fu where UPPER(fu.user_name) like 'ADMIN_' || UPPER(:1) || '%'";

方案2:在Java层拼接字符串(通用所有数据库)

这种方式更简单,也不用依赖数据库的拼接语法:

String query = "SELECT count(*) count from apps.fnd_user fu where UPPER(fu.user_name) like ?";
PreparedStatement stmt = conn.prepareStatement(query);
// 在Java层把前缀和变量拼接好,再传入占位符
stmt.setString(1, "ADMIN_" + companyName.toUpperCase());

如果是模糊匹配,同样可以在Java层加通配符:

stmt.setString(1, "ADMIN_" + companyName.toUpperCase() + "%");

关于管道符的使用

当然可以用管道符(||)进行拼接,但绝对不能把它放在单引号内部——它是SQL的字符串拼接运算符,必须作为SQL语法的一部分存在,而不是字符串常量的内容。只要按照方案1的写法使用,就能正常工作。

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

火山引擎 最新活动