2010-07-19 1 views
9

Am काफी MySQL और पर्ल में कुल नौसिखिया का उपयोग कर, लेकिन करने के लिए नए मुझे बाहर मदद करने के लिए किसी और स्क्रिप्ट को हैक करने की कोशिश कर रहा हूँ। मुझे here से स्क्रिप्ट मिली। यह अब तक बहुत अच्छा लग रहा है लेकिन यह विफल रहता है क्योंकि तालिकाओं में कुछ विदेशी कुंजी जांच चल रही है। मैं phpmyadmin के माध्यम से जाने के लिए और कोशिश करते हैं और उन्हें एक एक करके सभी को हटाकर उसकी जगह लेकिन यह करने के लिए होने की हमेशा के लिए ले जाता है और मेरी तीसरी बार है सकता है इस :(मेरा क्वेरी है, इस स्क्रिप्ट शामिल करने के लिए ammended जा सकता है:अक्षम विदेशी कुंजी की जांच को हटाने InnoDB टेबल पर्ल स्क्रिप्ट

`SET FOREIGN_KEY_CHECKS = 0; 

इससे पहले कि यह ड्रॉप तालिका आदेश चलाता है? मैं के माध्यम से स्क्रिप्ट का पालन करने की कोशिश की लेकिन स्क्रिप्ट (शायद अज्ञान/समझ की कमी के कारण) का एक निश्चित आदेश हिस्सा नहीं मिल सका। किसी भी मदद की बहुत सराहना।

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

क्या आप विदेशी कुंजी को अनिश्चितता से हटाना चाहते हैं, या बस डेटाबेस के साथ काम करते समय उन्हें अस्थायी रूप से कुछ भी जांचना नहीं है? – Wrikken

+0

(एक तरफ नोट पर, पर्ल कोड हो सकता है: 'मेरा $ sth = $ dbh-> तैयार करें ("SET FOREIGN_KEY_CHECKS = 0;"); $ sth-> execute') – Wrikken

+0

आप' -> do' का उपयोग कर सकते हैं यदि आप फिर से तैयार हैंडल का उपयोग कभी नहीं कर रहे हैं तो तैयार/निष्पादित जोड़ी का स्थान :) – hobbs

उत्तर

11

सेटिंग FOREIGN_KEY_CHECKS value शून्य करने के लिए:

SET FOREIGN_KEY_CHECKS = 0; 

... ड्रॉप स्क्रिप्ट विदेशी कुंजी की कमी उदाहरण विस्तृत निष्क्रिय कर देगा से पहले। चूंकि आपके पास एक MySQL इंस्टेंस पर एक से अधिक कैटलॉग/डेटाबेस हो सकते हैं, इसलिए यह जोखिम किसी अन्य डेटाबेस-वार पर प्रभाव डालता है।

सामान्य आदत को हटाने/बच्चों से पहले माता-पिता तालिका से डेटा छोटा इन महत्वपूर्ण निर्भरता के क्रम में स्क्रिप्ट के लिए है,।

+0

SQLs के समूह के निष्पादन के बाद इसे पुराने मान पर कैसे सेट करें? 'SET FOREIGN_KEY_CHECKS =?; धन्यवाद! –

+0

'सेट foreign_key_checks = 1;' इसके अलावा, मेरा मानना ​​है कि इस चर सत्र-आधारित है, इसलिए बाहर निकलने mysql भी चाल करेंगे। हालांकि मैं अभी भी सुनिश्चित करने के लिए ऊपर चला गया होगा। – matt

+0

यह बनाने के लिए एक बहुत ही महत्वपूर्ण नोट यह है कि "विदेशी_की_चेक को 1 पर सेट करना मौजूदा तालिका डेटा का स्कैन ट्रिगर नहीं करता है। इसलिए, तालिका में पंक्तियों को जोड़ा गया है जबकि विदेशी_की_चेक = 0 स्थिरता के लिए सत्यापित नहीं किया जाएगा।" ([mysql दस्तावेज़ीकरण] के माध्यम से (http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html#sysvar_foreign_key_checks)) – matt