具体来说,我需要在迭代表中的所有行时从表中删除一些行。 DBI在Java中有类似可更新结果集的东西吗?所以,如果我做了类似的事情:
$query_all = $dbh->prepare("select Id, X, Y, Z from MyTable");
$delete = $dbh->prepare("delete from MyTable where Id = ?");
$query_all->execute();
while ( my @res = $query_all->fetchrow_array() ){
my ($id, $x, $y, $z) = @res;
# fetch the IDs of any other rows that have the same X, Y, Z values
foreach ( the_duplicate_ids ){
$delete->execute($dup_id); # safe ??
# also delete from another table using $dup_id
}
}
......那可以吗?
为了给出一些上下文,我删除了对X,Y,Z列具有相同值的重复行,并且在每种情况下只留下一行(找到第一行)。如果这就是我正在做的事情,我只是在这3列上设置一个唯一索引以消除重复,但我还需要从另一个表中删除从MyTable
删除的每个重复的行。 / p>
最后,我编写了一个脚本来识别和收集我需要删除到数组中的行的所有ID,然后迭代该数组,删除两个表中的相关行。我仍然有兴趣找到原始问题的答案。如果我有时间,我会尝试自己回答,但如果有人已经知道我想听听它。
答案 0 :(得分:1)
您是否担心并发修改错误?
如果您正在使用交易,只要您在完成迭代后保存提交,它就不会成为问题。
但是,如果您使用自动提交,则可能是一个问题,因此解决方案将是:
伪代码 - 未经测试
#Loop through each row and note the records to delete
my @deathrow = ();
foreach my $row ( @resultset ) {
push $row->{id}, @deathrow;
}
#Now that we're done iterating, do all the deletes in one statement
$dbh->execute("DELETE WHERE id IN ( " . @deathrow . " )"); #something like that
答案 1 :(得分:0)
一个可能的解决方案是以下代码段:
my $dbh = DBI->connect("DBI:mysql:database=XXXX;host=localhost", "user", "pass", {'RaiseError' => 1, 'AutoCommit' => 0});
my $query_all = $dbh->prepare("select Id, X, Y, Z from MyTable");
eval {
my $delete = $dbh->prepare("delete from MyTable where Id = ?");
$query_all->execute();
while ( my @res = $query_all->fetchrow_array() ){
my ($id, $x, $y, $z) = @res;
# fetch the IDs of any other rows that have the same X, Y, Z values
foreach my $dup_id (@the_duplicate_ids){
$delete->execute($dup_id); # safe ??
# also delete from another table using $dup_id
}
}
$dbh->commit();
};
if ($@) {
print "Transaction rollback: $@";
$dbh->rollback();
}