Pregunta

Quiero hacer VACUUM en un momento determinado en una base de datos SQLite bajo Perl, pero siempre dice

  

DBD :: SQLite :: db qué fallaron: no puede aspirar desde el interior de una transacción

Entonces, ¿cómo lo hago?

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

Estoy utilizando AutoCommit => 0. Y pasa el error al:

$dbh->do('DELETE FROM soap');
$dbh->do('DELETE FROM result');
$dbh->commit; 
$dbh->do('VACUUM');
¿Fue útil?

Solución

Estoy suponiendo que haya AutoCommit => 0 en la llamada de conexión debido a las siguientes obras:

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

Usted no tiene que renunciar a las transacciones para poder VACUUM: Se puede utilizar el siguiente para que AutoCommit está encendido durante y después de la VACUUM VACUUM el estado AutoCommit está invertido de nuevo a lo que fuera. Añadir la comprobación de errores al gusto, si no se establece RaiseError.

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

Lo llaman:

do_vacuum($dbh);

Otros consejos

El DBI tiene confirmación automática activada de forma predeterminada. Apagarlo durante la conexión:

my $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 0 });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top