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

DBD :: SQLite :: db do не удалось: не удалось выполнить 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');
4
Galaxy 20 Авг 2009 в 05:33
1
 мой% attr = (RaiseError => 0, PrintError => 1, AutoCommit => 0);  мой $ dbh = DBI-> connect ('dbi: SQLite: dbname ='. $ file '', '', \% attr) или die $ DBI :: errstr;  
Я использую AutoCommit => 0. И ошибка возникает, пока:
 $ dbh-> do ('УДАЛИТЬ ИЗ мыла;');  $ dbh-> do ('УДАЛИТЬ ИЗ результата;');  $ dbh-> совершить;  $ dbh-> делать ('ВАКУУМ');  
 – 
Galaxy
20 Авг 2009 в 05:48

2 ответа

Лучший ответ

Я предполагаю, что у вас есть 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);
11
Sinan Ünür 20 Авг 2009 в 07:13
Итак, VACUUM требует AutoCommit = 1, чтобы отключить транзакцию. Спасибо.
 – 
Galaxy
20 Авг 2009 в 05:59
3
+1 Предложить local $dbh->{AutoCommit} = 1; и отказаться от переменной $ac.
 – 
pilcrow
20 Авг 2009 в 07:00
1
Почему я не знал, что вы можете использовать local для элементов лексических массивов и хешей? Perl по-прежнему преподносит мне несколько сюрпризов. : D
 – 
Michael Carman
20 Авг 2009 в 07:38
Я все время это забываю и вынужден проверять perldoc perlsub: perldoc.perl.org/perlsub.html#Temporary-Values-via-local%28%29
 – 
Sinan Ünür
20 Авг 2009 в 07:52

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

my $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 0 });
1
Chas. Owens 20 Авг 2009 в 05:38
1
Час. Я думаю, у вас все наоборот. AutoCommit должен быть включен, чтобы $dbh->do('VACCUM') происходило вне транзакции.
 – 
Sinan Ünür
20 Авг 2009 в 05:52