我正在使用这种方法。如果sql中有错误,则仅对asset_group的第一个ID进行回滚。其余的ID将被忽略。我做对了吗?

my $sql = "sql batch that update and insert depending on the condition";
$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
$dbh->{AutoCommit} = 0;

my $sth = $dbh->prepare($sql);
my @error = ();
my $num = 0;
foreach my $id (@asset_group) {
 next if ($id eq '');
 eval {
  $sth->bind_param(1, $id);
  $sth->bind_param(2, $vars{'other_id'});
  $sth->execute();

 };
 if ($@) {
  $dbh->rollback();
  push @error, $@
 } else {
  $dbh->commit();
 }
}

最佳答案

根据数据库的不同,您可能需要在开始更改之前发出begin work。我似乎记得Informix需要一个。

同样,您似乎在每次执行后都发出提交或回滚。一旦提交,就无法回滚。通常有人说

$dbh->begin_work;
eval {
    for my $id (@asset_group) {
        next if ($id eq '');
        $sth->execute($id, $vars{other_id});
    }
    1; #if it doesn't die then this will force it to return true
} or do {
    my $error = DBI->errstr;
    $dbh->rollback();
    die "could not insert rows: $error\n"
};
$dbh->commit();

注意我如何不使用$@$@untrustworthy

10-05 23:40
查看更多