3

使用 Informix 11.7,我尝试在 select 语句中使用 jdbc 位置参数执行 INSERT SELECT 查询,如下所示:

INSERT INTO table1(id, code, label) 
SELECT ?, ?, ? FROM table2
WHERE ...

参数设置如下:

 stmt.setString(1, "auniqueid");
 stmt.setString(2, "code");
 stmt.setString(3, "coollabel");

我收到以下错误:

线程“main”java.sql.SQLException 中的异常:发生了语法错误。

当位置参数“?” 放在其他地方它工作正常。我使用 PostgreSQL 没有这个问题。我的查询有什么问题?我使用 Informix JDBC Driver v3.70 JC1。

谢谢你的帮助。

4

2 回答 2

3

您是否期望通过占位符获得指定的列名?如果是这样,那你就一无所有了;您不能将占位符用于查询的结构元素,例如列名或表名。它们只能替换值。如果要动态 SQL 指定列,请使用动态 SQL;创建一个包含内容的字符串:

INSERT INTO table1(id, code, label)
    SELECT auniqueid, code, coollabel
      FROM table2
     WHERE ...

并与之合作。

如果这些占位符将是值,那么您将一遍又一遍地插入相同的值,对于查询返回的每一行一次,这通常不是您想要的;您只需使用 VALUES 子句插入一行,其中允许使用占位符:

INSERT INTO table1(id, code, label) VALUES(?, ?, ?);

那会很好用。

AFAIK,这种行为符合 SQL 标准。如果它在 PostgreSQL 中的工作方式不同,那么 PostgreSQL 提供了对该标准的扩展。

于 2013-02-01T19:14:30.237 回答
1

警告:我没有使用 Informix 的经验,答案基于一般观察

指定参数时,数据库需要知道每个参数的类型。如果选择列表中出现参数,则数据库无法推断参数的类型。某些数据库可能能够延迟该决定,直到它实际接收到参数,但大多数数据库将需要在解析时知道这一点。这可能是您收到错误的原因。

一些数据库——我不知道这是否适用于 Informix——允许你转换参数。例如:

SELECT CAST(? AS VARCHAR(20)), CAST(? AS VARCHAR(10)), CAST(? AS VARCHAR(5)) FROM ...

在这种情况下,数据库将能够推断参数类型并能够正确解析查询。

有了这个,我假设您没有尝试使用参数为选择列表指定列名,因为这是不可能的。

于 2013-02-01T16:57:48.517 回答