/ / Wie lässt sich die Identität von Datensätzen ermitteln, die mit DBIx :: Class :: ResultSet :: populate () eingefügt wurden? - SQL-Server, Perl, Dbix-Klasse

Was ist der beste Weg, die Identität von Datensätzen zu erhalten, die mit DBIx :: Class :: ResultSet :: populate () eingefügt wurden? - SQL-Server, Perl, Dbix-Klasse

Wie wir wissen, das bevölkern() Methode in DBIx :: Class :: ResultSet Bietet effiziente Masseneinsätze.

Wir müssen jedoch auch die Identität der eingefügten Datensätze für die weitere Verarbeitung abrufen.

Wir haben so etwas:

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

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

Aber wenn populate () in a verwendet wird nicht nichtig context, list context fungiert in diesem Fall nur als Wrapper für die create () -Methode und nicht als effizientes Bulk-Insert.

Was empfehlen Sie angesichts dieser Einschränkung, um Identitätsdatensätze als Masseneinfügung mit DBIx :: Class :: ResultSet :: populate () zu erhalten?

Antworten:

2 für die Antwort № 1

Wenn Sie einen automatisch inkrementierten Primärschlüssel haben,
und es gibt keine anderen Einfügungen zur gleichen Zeit,
Wäre es nicht eine Lösung, einfach N-1-Datensätze als Masseneintrag einzufügen und dann die letzten über die normale Erstellung einzufügen?

Zum Beispiel (für mich gearbeitet):

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

Bearbeiten: Wenn Sie überprüfen möchten, ob das Einfügen wie geplant verlaufen ist (anstatt es sicherzustellen oder auf jeden Fall), können Sie dies erweitern, indem Sie auch die ersten Informationen verschieben und einfügen und vergleichen, ob die Anzahl der IDs deaktiviert ist. Wenn dies der Fall ist, könnte die Methode standardmäßig die Datensätze über die Suche abrufen (kein Geschwindigkeitszuwachs, sorry). Wenn dies nicht der Fall ist, ist alles gut gelaufen und wir sind fertig.

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 } ];
}

Ich habe die erste Version tatsächlich in eine meiner add_to-Methoden eingefügt (angegebenes Array, bulk_insert), es scheint soweit gut zu funktionieren.

Ich werde die zweite Version eines Tages testen und melden, wenn es fehlschlägt ...


0 für die Antwort № 2

Dies ist, was ich getan habe, aber die Antwort von @bytepusher scheint effizienter zu sein. Posting zur Dokumentation aller möglichen Antworten.

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