【问题标题】:HSQLDB: column not foundHSQLDB:未找到列
【发布时间】:2016-01-26 03:02:00
【问题描述】:

我正在使用 HSQLDB 为我的应用程序编写一些功能测试。我的应用生成以下 SQL 请求:

SELECT 
CLIENT.account_id, 
CLIENT.client_code, 
SHIPPINGADDRESS10A9.account_id, 
SHIPPINGADDRESS10A9.address_code
FROM CLIENT 
LEFT JOIN ADDRESS SHIPPINGADDRESS10A9 
    ON SHIPPINGADDRESS10A9.address_code = CLIENT.shipping_address_code AND (SHIPPINGADDRESS10A9.account_id = 4) 
WHERE CLIENT.account_id = 4

此请求有效并且适用于我的代码(JDBC + MySQL)。当我尝试使用 HSQLDB 执行功能测试时,出现以下异常:

resultSet.findColumn("CLIENT.account_id"); //Works
resultSet.findColumn("SHIPPINGADDRESS10A9.account_id"); //Exception

Caused by: java.sql.SQLException: Column not found: SHIPPINGADDRESS10A9.account_id
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.findColumn(Unknown Source)
    at com.inventis.bw.data.DataBaseUtil.loadBean(DataBaseUtil.java:419)
    ... 33 more
Caused by: org.hsqldb.HsqlException: Column not found: SHIPPINGADDRESS10A9.account_id
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    ... 36 more

知道我在这里做错了什么吗?

编辑: 看起来问题来自表别名。

logger.debug("address account id => " + resultSet.findColumn("ADDRESS.account_id")); // Works
logger.debug("address account id => " + resultSet.findColumn("SHIPPINGADDRESS10A9.account_id")); //Exception

使用表名访问列值效果很好,但是如果我使用表别名,则会引发异常。有什么想法吗?

感谢您的帮助。

【问题讨论】:

  • 您应该接受@Gordon 的回答。从SQL 结果集中进行选择时,不应依赖表(别名)前缀。只需引用(别名)列名 without 前缀。制作唯一的列别名,你就做对了。
  • When selecting from an SQL result set, one should not rely on table (alias) prefixes. 为什么?我的代码基于别名完美运行,只有 HSQLDB 失败。
  • 例如,来自Oracle documentation:“列的标签用SQL AS子句指定。如果没有指定SQL AS子句,那么标签是列名。"另见问答here
  • 黑暗中的一枪:尝试通过将“LEFT JOIN ADDRESS SHIPPINGADDRESS10A9”更改为“LEFT JOIN ADDRESS AS SHIPPINGADDRESS10A9”来明确使用 AS。

标签: java sql left-join hsqldb functional-testing


【解决方案1】:

我想您的问题是两列具有相同的别名“account_id”,这会导致混淆。尝试给他们起不同的名字:

SELECT CLIENT.account_id as client_account_id,
       CLIENT.client_code, 
       SHIPPINGADDRESS10A9.account_id as shipping_account_id
       SHIPPINGADDRESS10A9.address_code

只是好奇,你可以这样写查询吗?

SELECT c.account_id as client_account_id,
       c.client_code, 
       a.account_id as shipping_account_id
       a.address_code
FROM CLIENT c LEFT JOIN
     ADDRESS a 
     ON a.address_code = c.shipping_address_code AND 
        a.account_id = c.account_id
WHERE c.account_id = 4;

这应该是等效的,并且清楚地表明您不需要在select 中返回两次account_id

【讨论】:

  • 嘿@Gordon Linoff,感谢您的回答。我更新了我的问题。看起来问题出在表别名而不是列本身。
  • 我接受您的回答,因为使用列上的别名有效,但您的解释并不准确。 HSQLB 不像 MySQL 那样处理别名。
  • @dbaq 是的,HSQLDB 不接受与列名组合的表别名。与列名一起使用时,它确实接受实际的表名。因此,如果您只使用address.account_id 并完全避免使用长表别名,它就可以工作。
【解决方案2】:

你应该尝试这个 SQL 请求来正确声明连接:

SELECT 
C.account_id, 
C.client_code, 
S.account_id, 
S.address_code
FROM CLIENT C,ADDRESS S
WHERE S.address_code = C.shipping_address_code AND C.account_id = 4

你会试试这个

resultSet.findColumn("C.account_id"); 
resultSet.findColumn("S.account_id"); 

【讨论】:

  • 不,我需要左连接。
【解决方案3】:

我喜欢 Gordon Linoff 的回答。我只是想补充一点,如果您希望它在 HSQLDB 中工作,您需要在连接字符串“;get_column_name=false”中指定 __

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多