2015-08-31 4 views
6

विशेष रूप से, मुझे तालिका में सभी पंक्तियों को फिर से भरते समय तालिका से कुछ पंक्तियों को हटाने की आवश्यकता है। क्या डीबीआई में जावा में एक अद्यतन करने योग्य परिणाम की तरह कुछ है? तो, अगर मैं कुछ ऐसा करता हूं:क्या पर्ल डीबीआई के साथ परिणामसेट को पुनरारंभ करते समय एक MySQL तालिका को अपडेट करना सुरक्षित है?

$query_all = $dbh->prepare("select Id, X, Y, Z from MyTable"); 
$delete = $dbh->prepare("delete from MyTable where Id = ?"); 
$query_all->execute(); 

while (my @res = $query_all->fetchrow_array()){ 
    my ($id, $x, $y, $z) = @res; 
    # fetch the IDs of any other rows that have the same X, Y, Z values 
    foreach (the_duplicate_ids){ 
     $delete->execute($dup_id); # safe ?? 
     # also delete from another table using $dup_id 
    } 
} 

... क्या यह ठीक है?

बस कुछ संदर्भ देने के लिए, मैं डुप्लिकेट पंक्तियों को हटा रहा हूं जिनके पास एक्स, वाई, जेड कॉलम के लिए समान मान हैं, और प्रत्येक मामले में केवल एक पंक्ति छोड़कर (पहला पाया गया)। अगर मैं ऐसा कर रहा था, तो मैं सिर्फ 3 कॉलम पर डुप्लिकेट को खत्म करने के लिए एक अनन्य इंडेक्स सेट अप करता था, लेकिन मुझे MyTable से हटाए गए प्रत्येक डुप्लिकेट के लिए दूसरी तालिका से एक पंक्ति को हटाने की भी आवश्यकता है।

अंत में, मैंने पंक्तियों के लिए सभी आईडी को पहचानने और एकत्र करने के लिए एक स्क्रिप्ट लिखी है जिसे मुझे किसी सरणी में हटाने की आवश्यकता है, फिर उस सरणी पर फिर से चलें, दोनों तालिकाओं से प्रासंगिक पंक्तियों को हटा दें। हालांकि मुझे मूल प्रश्न का उत्तर खोजने में अभी भी दिलचस्पी है। अगर मुझे समय मिलता है तो मैं इसे खुद जवाब देने की कोशिश करूंगा, लेकिन अगर कोई पहले से ही जानता है कि मैं इसे सुनना चाहता हूं।

+2

आपको एक ट्रिगर जोड़ना चाहिए जो पंक्ति को हटाए जाने पर आपकी द्वितीयक तालिका में संबंधित पंक्ति को हटा देता है प्राथमिक तालिका से। फिर आप अद्वितीय बाधा – Borodin

+0

जोड़ सकते हैं जो एक अच्छा समाधान की तरह लगता है, लेकिन यह वास्तव में मेरे लिए उपयुक्त नहीं होगा। मेरी आवश्यकताओं में थोड़ा बदलाव आया है, मुझे पहले की बजाय तालिका में जोड़े गए अंतिम डुप्लिकेट को पकड़ने की आवश्यकता है, और मुझे लगता है कि एक अनूठी बाधा केवल पहले रखती है। – RTF

उत्तर

1

आप एक समवर्ती संशोधन त्रुटि के बारे में चिंतित हैं?

यदि आप लेनदेन का उपयोग कर रहे हैं, तो यह तब तक कोई समस्या नहीं होगी जब तक आप इसे फिर से पूरा करने के बाद प्रतिबद्धता को सहेजते हैं।

हालांकि आप autocommit उपयोग कर रहे हैं यह एक समस्या हो सकती है और इसलिए समाधान होगा:

छद्म कोड ish - परीक्षण नहीं

#Loop through each row and note the records to delete 
my @deathrow =(); 
foreach my $row (@resultset) { 
    push $row->{id}, @deathrow; 
} 

#Now that we're done iterating, do all the deletes in one statement 
$dbh->execute("DELETE WHERE id IN (" . @deathrow . ")"); #something like that 
0

एक संभव समाधान कुछ के साथ होगा निम्नलिखित स्निपेट:

my $dbh = DBI->connect("DBI:mysql:database=XXXX;host=localhost", "user", "pass", {'RaiseError' => 1, 'AutoCommit' => 0}); 

my $query_all = $dbh->prepare("select Id, X, Y, Z from MyTable"); 

eval { 
    my $delete = $dbh->prepare("delete from MyTable where Id = ?"); 
    $query_all->execute(); 
    while (my @res = $query_all->fetchrow_array()){ 
     my ($id, $x, $y, $z) = @res; 
     # fetch the IDs of any other rows that have the same X, Y, Z values 
     foreach my $dup_id (@the_duplicate_ids){ 
      $delete->execute($dup_id); # safe ?? 
      # also delete from another table using $dup_id 
     } 
    }  
    $dbh->commit(); 
}; 

if ([email protected]) { 
    print "Transaction rollback: [email protected]"; 
    $dbh->rollback(); 
} 
संबंधित मुद्दे