获取使用DBIx :: Class :: ResultSet :: populate()插入的记录标识的最佳方法是什么?

时间:2014-10-31 07:06:06

标签: sql-server perl dbix-class

众所周知, DBIx :: Class :: ResultSet 中的 populate()方法提供了高效的批量插入。

但是,我们还需要获取插入记录的标识以供进一步处理。

我们有这样的事情:

my @created_records = $self->schema->instrument_rs->populate(\@records_to_create_rs);

foreach my $record ( @created_records ) {
    $id_of->{ $record->Name } = $record->Id;
}

但是,当populate()用于非void 上下文时,在这种情况下列出上下文,它只是作为create()方法的包装器而不是有效的批量插入

鉴于此限制,您建议使用DBIx :: Class :: ResultSet :: populate()来批量插入身份记录的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

如果您有自动递增的主键,
并且没有其他插入同时进行,
它不是简单地批量插入N-1记录,然后通过普通创建插入最后一个?

的解决方案

例如(为我工作):

my $last_info = pop @records_to_create_rs;
my $items = scalar(@records_to_create_rs);
$rs->populate( \@records_to_create_rs );
my $last = $rs->create( $last_info );
my ( $first_id, $last_id ) = ( $last->id - $items, $last->id );
my @inserted_ids = ( $first_id .. $last_id );

编辑:如果你想检查插入是否按照计划进行(而不是确保插入,或者无论如何),可以通过移动和插入第一个信息并比较id计数是否关闭来扩展。如果是,该方法可以默认通过搜索获得记录(然后没有速度增益,抱歉),如果不是,一切顺利,我们就完成了。

my $first_info = shift @records;
my $items = scalar( @records );
my $last_info = pop @records;
$rs->create( $first_info );
$rs->populate( \@records );
my $last = $rs->create( $last_info );
my $expected = $first_id +1;
if ( $expected == $last->id - $items ){
   return [ $first_id .. $last->id ];
}else{
   # get the records another way, I did not check this
   @records = $rs->search( \@records )->all;
   unshift @records, $first;
   push @records, $last;
   return [ map { $_->id } ];
}

我实际上将第一个版本放入我的add_to方法之一(给定数组,bulk_insert),到目前为止似乎工作正常。

我会测试那些日子的第二个版本并报告它是否失败......

答案 1 :(得分:0)

这就是我所做的,但@bytepusher的答案似乎更有效率。张贴所有可能答案的文件。

$self->schema->instrument_rs->populate(\@records_to_create_rs);

$created_records_rs = $self->schema->instrument_rs->search(
    { 'InstrumentTypeId' => $inst_type_id, },
    { order_by           => { -desc => 'Id' } }
)->slice(0,$records_to_create_count - 1);