插入选择不起作用
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 ...
在这种情况下,数据库将能够推断参数类型并能够正确解析查询。
我假设您没有尝试使用参数为选择列表指定列名,因为这是不可能的。
【讨论】:
以上是关于插入选择不起作用的主要内容,如果未能解决你的问题,请参考以下文章