2010-07-19 10 views
9

Sono abbastanza nuovo nell'usare MySQL e un novizio totale in Perl, ma sto provando a hackerare script di qualcun altro per aiutarmi. Ho ottenuto la sceneggiatura da here. Sembra fantastico finora, ma fallisce perché le tabelle hanno qualche controllo di chiave straniera in corso. Potrei passare attraverso phpMyAdmin e cercare di eliminarli tutti uno per uno, ma questo prende per sempre ed è la mia terza volta di dover fare questo :(La mia domanda è, può essere questo script ammended per includere:disabilita il controllo della chiave esterna eliminando le tabelle InnoDB Script Perl

`SET FOREIGN_KEY_CHECKS = 0; 

prima che si esegue il comando drop table? ho provato a seguire il copione attraverso ma non sono riuscito a trovare una parte di comando definitiva dello script (probabilmente a causa di ignoranza/mancanza di comprensione). Qualsiasi aiuto molto apprezzato.

#!/usr/bin/perl 

use strict; 
use DBI; 

my $hostname = ''; 
my $database = ''; 
my $username = ''; 
my $password = ''; 

my $dbh = DBI->connect("dbi:mysql:${database}:$hostname", 
    $username, $password) or die "Error: $DBI::errstr\n"; 

my $sth = $dbh->prepare("SHOW TABLES"); 
$sth->execute or die "SQL Error: $DBI::errstr\n"; 
my $i = 0; 
my @all_tables =(); 
while(my $table = $sth->fetchrow_array) 
{ 
    $i++; 
    print "table $i: $table\n"; 
    push @all_tables, $table; 
} 
my $total_table_count = $i; 

print "Enter string or regex to match tables to " 
    . "delete (won't delete yet): "; 
my $regex = <STDIN>; 
chomp $regex; 

$i = 0; 
my @matching_tables =(); 
foreach my $table (@all_tables) 
{ 
    if($table =~ /$regex/i) 
    { 
    $i++; 
    print "matching table $i: $table\n"; 
    push @matching_tables, $table; 
    } 
} 
my $matching_table_count = $i; 

if($matching_table_count) 
{ 
    print "$matching_table_count out of $total_table_count " 
    . "tables match, and will be deleted.\n"; 
    print "Delete tables now? [y/n] "; 
    my $decision = <STDIN>; 
    chomp $decision; 

    $i = 0; 
    if($decision =~ /y/i) 
    { 
    foreach my $table (@matching_tables) 
    { 
     $i++; 
     print "deleting table $i: $table\n"; 
     my $sth = $dbh->prepare("DROP TABLE $table"); 
     $sth->execute or die "SQL Error: $DBI::errstr\n"; 
    } 
    } 
    else 
    { 
    print "Not deleting any tables.\n"; 
    } 
} 
else 
{ 
    print "No matching tables.\n"; 
} 
+0

Si desidera rimuovere la chiave esterna a tempo indeterminato, o semplicemente fare in modo che non controllino nulla mentre si lavora con il database? – Wrikken

+0

(su una nota a margine, il codice perl potrebbe essere: 'my $ sth = $ dbh-> prepare (" SET FOREIGN_KEY_CHECKS = 0; "); $ sth-> execute') – Wrikken

+0

Puoi usare' -> do' in luogo di una coppia preparata/eseguita se non si userà mai più la maniglia preparata :) – hobbs

risposta

11

Impostazione FOREIGN_KEY_CHECKS value a zero:

SET FOREIGN_KEY_CHECKS = 0; 

... prima che gli script di rilascio disabilitino l'ampiezza dei vincoli di chiave esterna. Poiché è possibile avere più di un catalogo/database su un'istanza MySQL, questo rischia di influire su qualsiasi altro database.

L'abitudine generale è di scriverli in ordine di dipendenza dalla chiave, eliminando/troncando i dati dalle tabelle padre prima dei bambini.

+0

come riportarlo al vecchio valore dopo l'esecuzione di un gruppo di SQL? 'SET FOREIGN_KEY_CHECKS =?;' Grazie! –

+0

'SET foreign_key_checks = 1;' Inoltre, credo che questa variabile sia basata sulle sessioni, così anche l'uscita di mysql farà il trucco. Continuerò comunque a funzionare sopra per essere sicuro. – matt

+0

Una nota molto importante da fare è che "L'impostazione di foreign_key_checks su 1 non attiva una scansione dei dati della tabella esistenti. Pertanto, le righe aggiunte alla tabella mentre foreign_key_checks = 0 non saranno verificate per coerenza." (tramite [documentazione mysql] (http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html#sysvar_foreign_key_checks)) – matt

Problemi correlati