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

使用JdbcTemplate执行DELETE语句遇列索引越界问题求助

解决JdbcTemplate执行PostgreSQL带动态interval参数的DELETE语句报错问题

问题场景

执行以下JdbcTemplate代码时触发报错:

jdbcTemplate.update("DELETE FROM my_table WHERE created <= (NOW() - interval '? milliseconds')", 1);

报错信息:

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [DELETE FROM my_table WHERE created <= (NOW() - interval '? milliseconds')]; The column index is out of range: 1, number of columns: 0.; nested exception is org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.

在SQL编辑器中直接执行硬编码参数的语句可正常运行:

select * from my_table where created <= (NOW() - interval '1 milliseconds');

原因分析

你的推测完全正确:占位符?被包裹在单引号的字符串字面量'? milliseconds'中,JDBC驱动会将其视为普通文本,不会识别为可绑定的参数位置,导致代码传递的参数1找不到对应的占位符,触发索引越界错误。

解决方案

提供三种可行的写法,均能让JdbcTemplate正确识别参数占位符:

方案1:使用PostgreSQL的make_interval函数(推荐)

利用PostgreSQL内置的make_interval函数直接指定毫秒参数,无需拼接字符串:

jdbcTemplate.update("DELETE FROM my_table WHERE created <= NOW() - make_interval(milliseconds => ?)", 1);

方案2:拼接字符串后转换为interval类型

将数字参数与单位字符串拼接,再显式转为interval类型:

jdbcTemplate.update("DELETE FROM my_table WHERE created <= NOW() - (? || ' milliseconds')::interval", 1);

方案3:基于基础interval做乘法

用固定的1毫秒interval乘以参数值,实现动态时长:

jdbcTemplate.update("DELETE FROM my_table WHERE created <= NOW() - INTERVAL '1 millisecond' * ?", 1);

以上三种写法都能保持预编译语句的安全性,避免SQL注入风险,同时解决占位符无法识别的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:40:16