Почему $ dbh-> do ('VACUUM') не работает с Perl DBD :: SQLite? - PullRequest
4 голосов
/ 20 августа 2009

Я хочу сделать VACUUM в определенное время в базе данных SQLite под Perl, но он всегда говорит

Ошибка 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');

Ответы [ 2 ]

11 голосов
/ 20 августа 2009

Я предполагаю, что у вас есть 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: Вы можете использовать следующее, чтобы AutoCommit было включено для VACUUM, а после VACUUM состояние AutoCommit вернулся к тому, что это было. Добавьте проверку ошибок по вкусу, если вы не установите RaiseError.

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

Назовите это:

do_vacuum($dbh);
1 голос
/ 20 августа 2009

В DBI по умолчанию включен автокоммит. Выключите его во время подключения:

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