【问题标题】:java commons dbutils: multi-part identifier could not be boundjava commons dbutils:无法绑定多部分标识符
【发布时间】:2014-01-12 18:59:59
【问题描述】:

我正在执行这个查询:

 SELECT psq_id, question_text 
 FROM presales_question
 WHERE psq_id IN(SELECT zz.psq_id FROM productservice_psq as zz WHERE zz.ps_id = 1)

当我直接在 SQL Server Management Studio 中执行它时,它可以工作。
当我使用标准 Java 语句和结果集执行它时,它可以工作。
当我使用Apache Commons DBUtils library (v 1.5) 执行它时,我得到:

Exception in thread "main" java.sql.SQLException: com.microsoft.sqlserver.jdbc.SQLServerException: The multi-part identifier "zz.ps_id" could not be bound. Query: SELECT psq_id, question_text FROM presales_question  WHERE psq_id IN(SELECT zz.psq_id FROM productservice_psq as zz WHERE zz.ps_id = ?)  Parameters: [1]
at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:363)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:350)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:211)

看来问题不在于查询,而在于 dbutils 库。挖掘源代码,我看到当 dbutils 调用 Statement 的 getParameterMetaData() 方法时会引发错误。我仍然不确定如何解决这个问题。

我的临时解决方案是编辑 dbutils 库的源代码并禁用对 getParameterMetaData() 的调用(参见 AbstractQueryRunner.java 的第 196 行)。它所做的只是检查传入的参数计数是否与查询中找到的相匹配,如果 != 则抛出错误。我可以跳过该检查,因为如果参数不匹配,查询无论如何都会失败。

【问题讨论】:

  • 检查你的 jdbc 驱动,使用最新的库。
  • 我有最新的 sqljdbc4.jar 驱动程序。就像我说的,查询本身有效。问题是 getParameterMetaData() 抛出错误。

标签: java sql apache-commons-dbutils


【解决方案1】:

您的查询不同,请检查表名并重新尝试。

SELECT psq_id, text 
FROM ps_question
WHERE psq_id IN (
  SELECT zz.psq_id FROM productservice_psq as zz WHERE zz.ps_id = 1
)

失败的那个

SELECT psq_id, question_text 
FROM presales_question  
WHERE psq_id IN (
  SELECT zz.psq_id FROM productservice_psq as zz WHERE zz.ps_id = ?
)
  1. 第一个有文本,下一个有 question_text。
  2. 第一个查询的表名是 ps_question,另一个是 presales_question。

100% 确保查询正常,您不需要表 zz 的任何别名。您可以删除此详细信息。


可能是您使用的旧 jdbc 驱动程序。

下载最新的驱动,

http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774


尝试给出 1 并再次运行查询,它会运行吗?还是会失败?

改变 ?到 1

SELECT psq_id, question_text FROM presales_question  
WHERE psq_id IN (
  SELECT zz.psq_id FROM productservice_psq as zz WHERE zz.ps_id = ? <-- change 1
)

【讨论】:

  • 不同的参数只是我在发布时试图简化查询名称。我有来自 MS 的最新驱动程序。更改 1 没有帮助。
  • 我添加了 zz 别名来进行一些故障排除。我知道这没有必要,但没有它我会得到同样的错误。
  • 是的,简单查询有效。从单个表中选择的任何东西(不使用连接或嵌套选择)都有效。
  • 在使用别名时出现了一个错误(我认为它已经修复了一些版本),这就是我要求删除 zz 的原因,请参阅线程 groups.google.com/forum/#!topic/…
  • 好的。更多调试。删除 zz 别名并更改 ?到 1,它成功执行并且 getParameterMetaData() 工作。这是一个问题,因为我需要(更喜欢)使用带有 ? 的准备好的语句来防止 sql 注入
猜你喜欢
  • 2011-11-10
  • 2010-11-02
  • 2023-03-21
相关资源
最近更新 更多