HSQLDB: INSERT INTO ... (SELECT NULL, * FROM) 导致“列名重复”

Posted

技术标签:

【中文标题】HSQLDB: INSERT INTO ... (SELECT NULL, * FROM) 导致“列名重复”【英文标题】:HSQLDB: INSERT INTO ... (SELECT NULL, * FROM) leads to "duplicate column name" 【发布时间】:2018-10-08 18:47:05 【问题描述】:

在 HSQLDB 中,我有两个 TEXT 表,映射到 CSV 文件。参见项目CSV Cruncher。

CREATE TEXT TABLE session_telephony_pins ( Op VARCHAR(4092), id ... )

我正在尝试向这个“输入”表添加一列,以便结果对于每个表都有一个唯一的 ID。

所以这看起来很合乎逻辑:添加该列,定义为一个序列,

CREATE TEXT TABLE output ( crunchCounter BIGINT
  GENERATED BY DEFAULT AS SEQUENCE crunchCounter PRIMARY KEY, op VARCHAR(4092), ... )

然后使用null让DB选择值:

INSERT INTO output (SELECT NULL AS crunchCounter, * FROM apollo_session_occurrence)
-- I also tried withhout `AS ...`

但是如果失败:

SQLSyntaxErrorException duplicate column name in derived table

表格和列类型:

* APOLLO_SESSION_OCCURRENCE
  - OP                           CHARACTER VARYING
  - SESSION_OCCURRENCE_ID        SMALLINT
  - SESSION_ID                   SMALLINT
  - START_TIME                   TIMESTAMP
  - END_TIME                     TIMESTAMP
  - UID                          UUID
* OUTPUT
  - CRUNCHCOUNTER                BIGINT
  - OP                           CHARACTER VARYING
  - SESSION_OCCURRENCE_ID        CHARACTER VARYING
  - SESSION_ID                   CHARACTER VARYING
  - START_TIME                   CHARACTER VARYING
  - END_TIME                     CHARACTER VARYING
  - UID                          CHARACTER VARYING

我认为这在 mysql 中可行,但尚未测试。

类型应该不是问题。如果我删除crunchCounter 列并只执行INSERT INTO output (SELECT * FROM apollo_session_occurrence),它可以正常工作。

理论上我可以使用NEXT VALUE FOR crunchCounter,但这不会改变列元数据。当 HSQLDB 检查元数据时会发生这种情况。

发生了什么事?而且,

我应该如何用唯一列填充output 表?

编辑:有趣的是,它适用于其他表和专门命名的结果列:

INSERT INTO output (SELECT NULL AS crunchCounter,  jobName, buildNumber, config, ar, arFile, deployDur, warmupDur, scale,
  CAST(warmupDur AS DOUBLE) / CAST(deployDur AS DOUBLE) AS warmupSlower
  FROM concat ORDER BY deployDur)

* CONCAT
 - JOBNAME                      CHARACTER VARYING
 - BUILDNUMBER                  SMALLINT
 - CONFIG                       CHARACTER VARYING
 - AR                           CHARACTER VARYING
 - ARFILE                       CHARACTER VARYING
 - DEPLOYDUR                    SMALLINT
 - WARMUPDUR                    SMALLINT
 - SCALE                        SMALLINT
* OUTPUT
 - CRUNCHCOUNTER                BIGINT
 - JOBNAME                      CHARACTER VARYING
 - BUILDNUMBER                  CHARACTER VARYING
 - CONFIG                       CHARACTER VARYING
 - AR                           CHARACTER VARYING
 - ARFILE                       CHARACTER VARYING
 - DEPLOYDUR                    CHARACTER VARYING
 - WARMUPDUR                    CHARACTER VARYING
 - SCALE                        CHARACTER VARYING
 - WARMUPSLOWER                 CHARACTER VARYING

开始看起来像一个 HSQLDB 错误。

【问题讨论】:

【参考方案1】:

想通了。问题是 HSQLDB 将SELECT 1 AS foo, * FROM myTable 中的* 扩展为foo, foo, myTable.col1, ...

这是 IMO 的一个错误。 编辑:不是错误,但 HSQLDB 可以提供更好的错误消息。

解决方法:使用合格的通配符。

INSERT INTO output (SELECT NULL AS crunchCounter, 
        apollo_session_occurrence.* 
   FROM apollo_session_occurrence ...)

【讨论】:

这不是错误。只有SELECT * FROM 是合法的语法。 HSQLDB 在 SourceForge 上有一个错误跟踪器,链接自 hsqldb.org 嗨,弗雷德!感谢您的参与。这是一种合法的语法,但这是我遇到的第一个将其扩展为 SELECT 的结果的数据库。通常它会扩展到来自 FROM 子句的所有列。我会提交一个错误/RFC 并在那里解释。 在您的情况下,当有任何其他列时,它甚至不会扩展 *。使用了重名的错误信息,不完全正确。 @fredt,当然,我假设它做了什么,我真的不知道。那么错误信息应该是什么? 我认为没有必要提供确切的信息来提及这种情况..

以上是关于HSQLDB: INSERT INTO ... (SELECT NULL, * FROM) 导致“列名重复”的主要内容,如果未能解决你的问题,请参考以下文章

使用 HSQLDB 选择 INTO

HSQLDB:REPLACE INTO 表抛出 org.hsqldb.HsqlException:完整性约束违规:

使用 hsqldb 了解 MERGE INTO

如何知道 Hsqldb "MERGE INTO" 是不是进行了插入或更新

insert into 语句错误

易语言 insert into