2010-07-19 15 views
9

Perl de MySQL ve toplam acemi kullanmak oldukça yeni ama birileri bana yardımcı olmak için elses komut dosyası kesmek için çalışıyor. Komut dosyasını here'dan aldım. Şimdiye kadar harika görünüyor ama masaların bazı yabancı anahtar kontrolleri devam ettikçe başarısız oluyor. Ben phpmyadmin geçmesi ve denemek ve onları tek bütün tek silmek ama bunu yapmak zorunda benim üçüncü kez sonsuza dek sürer ve bir olabilir, bu komut içerecek şekilde ermesi edilebilir Benim sorgu :(:InnoDB tabloları silme yabancı anahtar kontrolü devre dışı Perl Komut Dosyası

`SET FOREIGN_KEY_CHECKS = 0; 

o damla tablo komutunu dolmadan? içinden senaryoyu takip etmeye çalıştım ama (muhtemelen anlayış cehalet/eksikliği) script kesin komut parçasını bulamadık. Herhangi bir yardım büyük takdir.

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

Yabancı anahtarın süresiz olarak kaldırılmasını mı yoksa veritabanıyla çalışırken herhangi bir şeyi geçici olarak kontrol etmesini istemiyor musunuz? – Wrikken

+0

(bir yan notta, perl kodu olabilir: 'my $ sth = $ dbh-> hazırla (" SET FOREIGN_KEY_CHECKS = 0; "); $ sth-> execute ') – Wrikken

+0

' -> do' içinde kullanabilirsiniz Hazırlanan tutamacını bir daha asla kullanmayacaksanız, bir hazırlık/yürütme çiftinin yeri :) – hobbs

cevap

11

Ayar FOREIGN_KEY_CHECKS value sıfır olarak:

SET FOREIGN_KEY_CHECKS = 0; 

... bırakma komut dosyalarından önce, yabancı anahtar kısıtlamalarını geçersiz kılar. Bir MySQL örneğinde birden fazla katalog/veritabanınız olabileceğinden, bu durum veritabanında herhangi bir şeyi etkileme riski taşır.

Genel alışkanlık, bunları temel bağımlılık sırasına göre sıralamak, alt tablolardaki verileri çocuklardan önce silmek/kesmek.

+0

Bir grup SQL'in çalıştırılmasından sonra eski değere nasıl geri dönülür? SET FOREIGN_KEY_CHECKS =?; 'Teşekkürler! –

+0

'SET foreign_key_checks = 1;' Ayrıca, bu değişkenin oturum tabanlı olduğuna inanıyorum, bu yüzden mysql'den çıkmak da hile yapacaktır. Yine de emin olmak için yukarıda koşuyordum. – matt

+0

Yapılması gereken çok önemli bir not: "Yabancı_çık_çık ayarlarının 1 olarak ayarlanması, mevcut tablo verilerinin taranmasını tetiklemez. Bu nedenle, yabancı_key_checks = 0 iken tabloya eklenen satırlar tutarlılık açısından doğrulanmayacaktır." ([mysql belgeleri] aracılığıyla (http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html#sysvar_foreign_key_checks)) – matt

İlgili konular