【问题标题】:Why does $dbh->do('VACUUM') fail with Perl's DBD::SQLite?为什么 $dbh->do('VACUUM') 会因 Perl 的 DBD::SQLite 而失败?
【发布时间】:2009-08-20 01:33:18
【问题描述】:

我想在某个时间在 Perl 下的 SQLite 数据库上做VACUUM,但它总是说

DBD::SQLite::db 失败:不能从事务中 VACUUM

那么我该怎么做呢?

my %attr = ( RaiseError => 0, PrintError => 1, AutoCommit => 0 );
my $dbh = DBI->connect('dbi:SQLite:dbname='.$file'','',\%attr) 
    or die $DBI::errstr;

我正在使用AutoCommit => 0。错误发生在:

$dbh->do('DELETE FROM soap');
$dbh->do('DELETE FROM result');
$dbh->commit; 
$dbh->do('VACUUM');

【问题讨论】:

  •  我的 %attr = ( RaiseError => 0, PrintError => 1, AutoCommit => 0 );我的 $dbh = DBI->connect('dbi:SQLite:dbname='.$file'','',\%attr) 或死 $DBI::errstr; 
    我正在使用 AutoCommit => 0 。并且错误发生在:
     $dbh->do('DELETE FROM soap;'); $dbh->do('从结果中删除;'); $dbh->提交; $dbh->do('VACUUM'); 

标签: sql perl sqlite dbi vacuum


【解决方案1】:

我假设您在 connect 调用中有AutoCommit => 0,因为以下方法有效:

#!/usr/bin/perl

use strict;
use warnings;

use DBI;

my $dbh = DBI->connect('dbi:SQLite:test.db', undef, undef,
    { RaiseError => 1, AutoCommit => 1}
);

$dbh->do('VACUUM');

$dbh->disconnect;

您不必为了能够VACUUM而放弃事务:您可以使用以下命令为VACUUM打开AutoCommit,在VACUUM之后AutoCommit状态为恢复到原来的样子。如果不设置RaiseError,请添加错误检查。

sub do_vacuum {
    my ($dbh) = @_;
    local $dbh->{AutoCommit} = 1;
    $dbh->do('VACUUM');
    return;
}

叫它:

do_vacuum($dbh);

【讨论】:

  • 所以,VACUUM 需要 AutoCommit=1 来禁用事务。谢谢。
  • +1 建议 local $dbh->{AutoCommit} = 1; 并放弃 $ac 变量。
  • 为什么我不知道您可以在 lexical 数组和散列的元素上使用local? Perl 仍然给我一些惊喜。 :D
  • 我一直都忘记了,必须检查perldoc perlsubperldoc.perl.org/perlsub.html#Temporary-Values-via-local%28%29
【解决方案2】:

默认情况下,DBI 已启用自动提交。在连接过程中关闭它:

my $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 0 });

【讨论】:

  • 查斯。我想你把它弄反了。 AutoCommit 需要打开,$dbh->do('VACCUM') 才能在事务之外发生。
猜你喜欢
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 2020-10-14
  • 1970-01-01
  • 2012-04-06
相关资源
最近更新 更多