【问题标题】:How to do an insert with multiple rows in Informix SQL?如何在 Informix SQL 中插入多行?
【发布时间】:2012-09-02 20:34:39
【问题描述】:

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

下面的代码插入一行,效果很好:

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);

有没有办法让它工作,还是我需要运行许多插入?

【问题讨论】:

    标签: sql informix


    【解决方案1】:

    这是一个简单的批量插入解决方案,选择部分解决其余部分

    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 )
    ;
    

    【讨论】:

    • 不需要像 cursos 或任何其他类型或复杂编码之类的特殊功能,在 dapper 中循环您的项目示例,构造查询并执行..!,不需要联合和选择,ES MUY FEO ESO ,,, 优雅!:)
    【解决方案2】:

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

    COLLECTION 值创建TABLE 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))
    

    【讨论】:

    • 请注意,如果您在 JDBC PreparedStatement 中对行进行参数化,您必须显式地转换每个值,例如row(?::int, ?::text).
    【解决方案3】:

    你总是可以这样做:

    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 接受 INSERT .. SELECT 语句中的 UNION ALL 是必要的)。

    【讨论】:

    • Informix 需要一个 FROM 子句及其 SELECT 语句。
    • 哇哦。好的 - 我将把这个答案留在这里,以防它帮助使用 Informix 以外的数据库的人遇到类似问题。
    • 即使我添加了一个 from 子句,我也只能使用 select 而不是 insert。这可能是因为我在基本 Informix 功能之上使用了一个附加层,所以这个附加层可能是问题所在。它可能对其他人有用吗?
    【解决方案4】:

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

    LOAD FROM "externalfile" INSERT INTO mytmptable;
    

    但是,这些值必须用竖线“|”分隔符号,或任何您设置的 DBDELIMITER 环境变量。

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

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

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

    【讨论】:

      【解决方案5】:

      如您所见,您不能在 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 技术,但是您需要在 Informix 的每个 SELECT 中使用 FROM 子句。您可以指定:

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

      在我的数据库中,我有一个表 dual,其中有一行,或者同义词 dualsysmaster:"informix".sysdual 的同义词。如果数据库是“正常的”,你可以不用这些语句的"informix". 部分;如果您的数据库是 Informix MODE ANSI 数据库,则所有者名称至关重要。

      【讨论】:

      • 谢谢。我实际上正在使用一个在 Informix 之上添加另一层的系统,并且不得不求助于多个插入。其中大约 1400 个花了大约 2 分钟,但临时表在系统中足够持久,我不需要经常重复。
      猜你喜欢
      • 2017-12-23
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      • 2011-09-10
      • 1970-01-01
      • 2011-04-20
      相关资源
      最近更新 更多