2009-08-20 5 views
4

Ich möchte VACUUM zu einem bestimmten Zeitpunkt auf einer SQLite-Datenbank unter Perl tun, aber es sagt immer

DBD :: SQLite :: db fehlgeschlagen tun: können sie nicht VACUUM aus einer Transaktion

Also, wie mache ich das?

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

Ich verwende AutoCommit => 0. Und der Fehler passiert während:

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

 my %attr = ( RaiseError => 0, PrintError => 1, AutoCommit => 0); my $dbh = DBI->connect('dbi:SQLite:dbname='.$file'','',\%attr) or die $DBI::errstr; 
Ich bin mit AutoCommit => 0. Und der Fehler passiert während:
 $dbh->do('DELETE FROM soap;'); $dbh->do('DELETE FROM result;'); $dbh->commit; $dbh->do('VACUUM'); 
Galaxy

Antwort

11

Ich gehe davon aus Sie haben AutoCommit => 0 in der Verbindungs ​​Aufruf, da die folgenden Werke:

#!/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; 

Sie müssen nicht aufgeben müssen, auf Transaktionen zu können, VACUUM: Sie können Folgendes verwenden, so dass AutoCommit für VACUUM aktiviert ist und nach VACUUM der AutoCommit-Status wieder auf das zurückgesetzt wird, was auch immer es war. Fügen Sie eine Fehlerprüfung hinzu, um zu testen, wenn Sie RaiseError nicht festlegen.

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

Nennen Sie es:

do_vacuum($dbh); 
+0

VACUUM benötigt also AutoCommit = 1, um die Transaktion zu deaktivieren. Danke. – Galaxy

+3

+1 Schlagen Sie 'local $ dbh -> {AutoCommit} = 1;' vor und verzichten Sie auf die Variable '$ ac'. – pilcrow

+1

Warum wusste ich nicht, dass Sie 'local' für Elemente von * lexikalischen * Arrays und Hashes verwenden könnten? Perl hat noch ein paar Überraschungen für mich. : D –

1

Der DBI hat Autocommit standardmäßig aktiviert. Schalten Sie es während der connect ab:

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

Chas. Ich denke du hast es umgekehrt. 'AutoCommit' muss aktiviert sein, damit' $ dbh-> do ('VACCUM') 'außerhalb einer Transaktion auftritt. –

Verwandte Themen