插入选择不起作用

Posted

技术标签:

【中文标题】插入选择不起作用【英文标题】:INSERT SELECT not working 【发布时间】:2013-02-01 16:05:23 【问题描述】:

使用 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。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

您是否希望通过占位符获得指定的列名?如果是这样,那你就一无所有了;您不能将占位符用于查询的结构元素,例如列名或表名。它们只能替换值。如果要动态 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 提供了对该标准的扩展。

【讨论】:

不,这不是我想要做的。我想通过占位符指定列值?并一次插入多行以提高性能。事实上,我的 SELECT 查询有点复杂,有一个 NOT EXISTS 子句过滤结果。当然,它可以使用 INSERT VALUES 语法,但我必须将我的过程分成两部分:首先是 SELECT 查询,它将返回我要插入的值,然后是多个 INSERT VALUES 查询,循环 SELECT 的结果。 好的;我不确定你为什么要一遍又一遍地插入相同的值,但如果这是你想要的,那么投射占位符将起作用(如果 Mark Rotteveel 还没有提出建议,这将是我的下一个建议,虽然我可能很想建议使用?::VARCHAR(16) 表示法而不是SQL 标准CAST(? AS VARCHAR(16)))。所以,你没事。 (简要说明您要达到的效果会有助于避免像这个答案那样走弯路。您的问题没有提到您正在尝试插入相同数据的许多副本。) 对不起,我不够清楚。事实上,这与我想一次又一次地插入的值并不完全相同。我的 SELECT 子句是这样的:SELECT table2.id, 'fixedvalue', 'fixedvalue'。我最终选择手动构建我的查询,而不是使用 JDBC 占位符来避免 SQL 类型之间的可移植性问题,并防止数据库模式修改。无论如何,感谢您的帮助!【参考方案2】:

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

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

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

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

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

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

【讨论】:

以上是关于插入选择不起作用的主要内容,如果未能解决你的问题,请参考以下文章

插入选择存储过程不起作用插入NULL

批量插入后选择在 MS access 数据库中不起作用

带有内部查询的 SQL 插入语句不起作用

Oracle Forms 10g,多次插入和更新不起作用

追加后Jquery选择器不起作用

PHP(Wordpress) - 选择多个 - 显示“选定”状态不起作用