简体   繁体   English

为什么$ dbh-> do('VACUUM')在Perl的DBD :: SQLite中失败?

[英]Why does $dbh->do('VACUUM') fail with Perl's DBD::SQLite?

I want to do VACUUM at a certain time on a SQLite database under Perl, but it always says 我想在特定时间在Perl下的SQLite数据库上执行VACUUM ,但它总是说

DBD::SQLite::db do failed: cannot VACUUM from within a transaction DBD :: SQLite :: db执行失败:无法从事务内进行抽真空

So how do I do this? 那么我该怎么做呢?

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

I am using AutoCommit => 0 . 我正在使用AutoCommit => 0 And the error happens while: 而错误发生在:

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

I am assuming you have AutoCommit => 0 in the connect call because the following works: 我假设您在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;

You don't have to give up on transactions to be able to VACUUM : You can use the following so that AutoCommit is turned on for VACUUM and after the VACUUM the AutoCommit state is reverted back to whatever it was. 你不必放弃交易能够VACUUM :您可以使用以下,这样AutoCommit被开启VACUUM和后VACUUMAutoCommit状态恢复到不管它是什么。 Add error checking to taste if you do not set RaiseError . 如果未设置RaiseError则添加错误检查以RaiseError

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

Call it: 称它为:

do_vacuum($dbh);

The DBI has autocommit turned on by default. 默认情况下,DBI已自动提交。 Turn it off during the connect: 在连接期间将其关闭:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM