如何在Informix SQL中插入多行?

时间:2012-09-09 23:37:16

标签: sql informix

我想用一个insert语句插入多行。

以下代码插入一行,并且工作正常:

create temp table mytmptable
(external_id char(10),
int_id integer,
cost_amount decimal(10,2)
) with no log;

insert into mytmptable values 
('7662', 232, 297.26);

select * from mytmptable;

我已尝试将插件更改为此,但它会出现语法错误:

insert into mytmptable values 
('7662', 232, 297.26),
('7662', 232, 297.26);

有没有办法让它工作,或者我是否需要运行多个插入?

5 个答案:

答案 0 :(得分:6)

您可以随时执行以下操作:

insert into mytmptable
select * 
from (
  select '7662', 232, 297.26 from table(set{1})
  union all
  select '7662', 232, 297.26 from table(set{1})
)

非常确定这是标准的SQL并且适用于Informix(派生表是Informix在UNION ALL语句中接受INSERT .. SELECT所必需的)。

答案 1 :(得分:4)

如您所见,您不能在使用Informix的单个INSERT语句中使用多个值列表。

最简单的解决方案是使用多个INSERT语句,每个语句都包含一个值列表。

如果您正在使用诸如ESQL / C之类的API并且您担心性能,那么您可以创建一个INSERT游标并重复使用它。这将保存插入,直到缓冲区已满,或者您刷新或关闭光标:

$ PREPARE p FROM "INSERT INTO mytmptable VALUES(?, ?, ?)";
$ DECLARE c CURSOR FOR p;
$ OPEN c;
while (...there's more data to process...)
{
    $PUT c USING :v1, :v2, :v3;
}
$ CLOSE c;

变量v1v2v3是用于保存要插入的字符串和数字的主变量。 (如果愿意,您可以选择在循环中使用$ FLUSH c;。)因为这会缓冲值,所以非常有效。当然,您也可以在循环中使用$ EXECUTE p USING :v1, :v2, :v3;;也放弃了对该陈述的每行准备。

如果您不介意编写详细SQL,可以使用Matt Hamilton建议的UNION技术,但每个SELECT中都需要一个FROM子句和Informix。您可以指定:

  • FROM "informix".systables WHERE tabid = 1
  • FROM sysmaster:"informix".sysdual
  • 使用其他一些技术来确保SELECT具有FROM子句,但只生成一行数据。

在我的数据库中,我有一个表dual,其中有一行,或者是同义词dual,它是sysmaster:"informix".sysdual的同义词。如果数据库是“正常”,你可以在没有这些陈述的"informix".部分的情况下离开;如果您的数据库是Informix MODE ANSI数据库,则所有者名称至关重要。

答案 2 :(得分:3)

您还可以通过将值存储在外部文件中并在dbaccess中执行以下语句来插入多行:

LOAD FROM "externalfile" INSERT INTO mytmptable;

但是,值必须通过管道“|”进行DELIMITED符号,或者您设置DBDELIMITER环境变量的任何内容。

如果您正在使用管道分隔符,则外部文件中的数据将如下所示:

7662|232|297.26|
7663|233|297.27|
...

请注意,外部文件中的数据必须正确格式化或能够转换为成功插入每个mytmptable.column数据类型。

答案 3 :(得分:2)

在某些版本的Infomix中,您可以使用TABLE关键字后跟一个COLLECTION数据类型的值(例如LIST集合)来构建虚拟表。在您的情况下,使用LIST构造函数语法使用Unnamed Row ROW(...)类型的值。

TABLE值创建COLLECTION http://www.ibm.com/support/knowledgecenter/SSGU8G_11.50.0/com.ibm.sqls.doc/ids_sqs_1375.htm

ROW(...)构造语法,用于Unnamed Row数据类型的文字 http://www.ibm.com/support/knowledgecenter/SSGU8G_11.50.0/com.ibm.sqlr.doc/ids_sqr_136.htm

示例:

select * 
from TABLE(LIST{
  ROW('7662', 232, 297.26),
  ROW('7662', 232, 297.26)
}) T(external_id, int_id, cost_amount)
into temp mytmptable with no log

在上面,数据类型由值隐含,但是在需要时,您可以在行构造函数中显式地将每个值转换为所需的数据类型,如下所示:

ROW('7662'::char(10), 232::integer, 297.26::decimal(10,2))

答案 4 :(得分:0)

这是批量插入的简单解决方案,其中SELECT部分​​解决了其余问题

INSERT INTO cccmte_pp 
( cmte, pref, nro, eje, id_tri, id_cuo, fecha, vto1, vto2, id_tit, id_suj, id_bie, id_gru ) 
SELECT * FROM TABLE (MULTISET { 
row('RC', 4, 10, 2020, 1, 5, MDY(05,20,2020), MDY(05,20,2020),MDY(05,27,2020),101, 1, 96, 1 ), 
row('RC', 4, 11, 2020, 1, 5, MDY(05,20,2020), MDY(05,20,2020),MDY(05,27,2020),101, 1, 96, 1 ) }) 
AS t( cmte, pref, nro, eje, id_tri, id_cuo, fecha, vto1, vto2, id_tit, id_suj, id_bie, id_gru )
;