如何在redstone_mapper_pg中插入多行的正确方法?

时间:2015-04-27 16:34:52

标签: postgresql asynchronous dart

我使用redstone_mapper_pg,我需要在数据库表中插入许多行:

class Rate {
  @Field() String zone_id;
  @Field() String cost;
}

@app.Route("/rplan", methods: const [app.POST])
addRPlan(@Decode() List<Rate> rate) async {
  try {
    await pgsql.execute('begin');
    rate.forEach((row) async {
      try {
        await pgsql.execute('insert into t_rate (zone_id,cost) '
          'values (@zone_id,@cost)', row);
      } catch(err) {
        await pgsql.execute('rollback');
        return new Future.error(err);
      }
    });
  } catch(err) {
    await pgsql.execute('rollback');
    return new Future.error(err);
  }
  await pgsql.execute('end');
  return new Future.value('OK');
}
  1. 在Dart postgresql驱动程序中,单独插入的循环是否正确插入多行?
  2. 如果我如上所述使用rate.forEach((row) async {我的执行链 begin-end-insert-insert 错误,因为.forEach方法异步调用参数函数。 rate.forEach(await (row) async {也是如此。使用await rate.forEach(await (row) async {给出右链 begin-insert-insert-end ,但插入是相对于 begin-end 异步执行的。只有标准for(int i=0; i<rate.length; i++) {循环才能提供所需的结果。有没有办法在我的代码中使用.forEach方法?

1 个答案:

答案 0 :(得分:2)

  1. 在一个更大的语句(来源https://kaiv.wordpress.com/2007/07/19/faster-insert-for-multiple-rows/
  2. 中插入多个记录会更有效率

    多行插入SQL文件

    $finish

    多个插入语句SQL文件

    insert into things (thing) values ('thing nr. 0'),
    ('thing nr. 1'),
    ('thing nr. 2'),
    ('thing nr. 3'),
    ...
    ('thing nr. 99999),
    ('thing nr. 100000);
    
    1. 使用
    2. begin;
      insert into things (thing) values ('thing nr. 0');
      insert into things (thing) values ('thing nr. 1');
      insert into things (thing) values ('thing nr. 2');
      ....
      insert into things (thing) values ('thing nr. 99999');
      insert into things (thing) values ('thing nr. 100000');
      commit;
      

      而不是

      await for(row in rate) {
        try {
          await pgsql.execute('insert into t_rate (zone_id,cost) '
            'values (@zone_id,@cost)', row);
        } catch(err) {
          await pgsql.execute('rollback');
          return new Future.error(err);
        }
      });