2014-02-26 2 views
0

다른 데이터베이스의 내용을 기반으로 데이터베이스의 행을 업데이트, 삽입 및 삭제하는 코드를 작성하려고합니다. 이는 결국 다른 기준에 따라 자동으로 발생합니다. 목표는 테이블을 동일하게 만드는 것입니다. 데이터베이스 복제는 옵션이 아닙니다.해시 배열이 아닌 경우 Perl

이 질문은 실제로 MYSQL 또는 DBI 모듈에 관한 것이 아니라 두 개의 배열을 비교하는 것입니다.

나는 두 개의 해시 배열을 만들기 위해 fetchall_arrayref({})을 사용했다. 이것은 내가 다른처럼 할 데이터베이스 테이블의 배열의 예는, 그것을이다

[ 
    { DESCRIPTION => "Default", ID => 0, NAME => "Default", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 1, NAME => "Custom 1", VERSION => "1.2" }, 
    { DESCRIPTION => "",  ID => 2, NAME => "Custom 2", VERSION => "2.0" }, 
    { DESCRIPTION => "",  ID => 3, NAME => "Custom 3", VERSION => "6.0" }, 
    { DESCRIPTION => "",  ID => 5, NAME => "Custom 5", VERSION => "1.0" }, 
] 

:

는 내 코드에 $profile입니다 원본 데이터베이스 테이블의 배열의 예입니다 내 코드에 $profile2입니다 :

[ 
    { DESCRIPTION => "Default", ID => 0, NAME => "Default", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 1, NAME => "Custom 1", VERSION => "1.1" }, 
    { DESCRIPTION => "",  ID => 2, NAME => "Custom 2", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 3, NAME => "Custom 3", VERSION => "6.0" }, 
    { DESCRIPTION => "",  ID => 4, NAME => "Custom 4", VERSION => "1.0" }, 
] 

다음은 ID가 두 테이블에있는 항목을 업데이트하기 위해 근무하고 다음

,686을

$profile의 ID가 $profile2이 아니고 $profile2 (my $insert = 'INSERT INTO PROFILE(ID,VERSION,NAME,DESCRIPTION) VALUES('."\'$id\'".','."\'$ver\'".','."\'$name\'".','."\'$desc\'".');';)의 데이터베이스 테이블에 해당 행이 삽입되어 있는지 확인하려면 코드가 필요합니다. ID가 $profile2이고 $profile이 아닌지 확인한 후 $profile2 데이터베이스 (my $update = 'DELETE FROM PROFILE WHERE ID='."\'$id2\'".';';)에서 행을 삭제하는 코드가 필요합니다.

도움을 주시면 감사하겠습니다. 감사!

+3

응! ' " '". $ var. "'"'을 사용하지 마십시오! 자리 표시 자나'$ dbh-> quote ($ var)'를 사용하십시오. – ikegami

답변

0

이 방법에 대해 :

use Data::Dumper; 
use strict; 

my $profile1 = [ 
    { DESCRIPTION => "Default", ID => 0, NAME => "Default", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 1, NAME => "Custom 1", VERSION => "1.2" }, 
    { DESCRIPTION => "",  ID => 2, NAME => "Custom 2", VERSION => "2.0" }, 
    { DESCRIPTION => "",  ID => 3, NAME => "Custom 3", VERSION => "6.0" }, 
    { DESCRIPTION => "",  ID => 5, NAME => "Custom 5", VERSION => "1.0" }, 
]; 

my $profile2 = [ 
    { DESCRIPTION => "Default", ID => 0, NAME => "Default", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 1, NAME => "Custom 1", VERSION => "1.1" }, 
    { DESCRIPTION => "",  ID => 2, NAME => "Custom 2", VERSION => "1.0" }, 
    { DESCRIPTION => "",  ID => 3, NAME => "Custom 3", VERSION => "6.0" }, 
    { DESCRIPTION => "",  ID => 4, NAME => "Custom 4", VERSION => "1.0" }, 
]; 

sub findUpdates{ 
    my ($updated, $toBeUpdated) = @_; 
    my @IDs2update; 
    my %index = map {$_->{ID} => $_} @$toBeUpdated; 
    foreach(@$updated){ 
    push @IDs2update, $_ unless defined $index{$_->{ID}}; 
    } 
    return \@IDs2update; 
} 

my $addIntoProfile2 = findUpdates($profile1, $profile2); 
my $deleteFromProfile1 = findUpdates($profile2, $profile1); 

print "Add into profile 2:\n"; 
print Dumper($addIntoProfile2); 
print "\n"; 
print "Delete from profile 1:\n"; 
print Dumper($deleteFromProfile1); 

출력 :

Add into profile 2: 
$VAR1 = [ 
      { 
      'ID' => 5, 
      'NAME' => 'Custom 5', 
      'DESCRIPTION' => '', 
      'VERSION' => '1.0' 
      } 
     ]; 

Delete from profile 1: 
$VAR1 = [ 
      { 
      'ID' => 4, 
      'NAME' => 'Custom 4', 
      'DESCRIPTION' => '', 
      'VERSION' => '1.0' 
      } 
     ]; 
2
my @ids_in_p1 = map $_->{ID}, @$profile1; 
my @ids_in_p2 = map $_->{ID}, @$profile2; 

my $ids_in_p1 = map { $_ => 1 } @ids_in_p1; 
my $ids_in_p2 = map { $_ => 1 } @ids_in_p2; 

for my $id (grep !$ids_in_p2{$_}, @ids_in_p1) { 
    print("In p1 but not in p2: $id\n"); 
} 

for my $id (grep !$ids_in_p1{$_}, @ids_in_p2) { 
    print("In p2 but not in p1: $id\n"); 
} 
-1

당신은 단순히 당신이 $profile2에서 같은 ID가 발생할 때 당신은 배열에서 해당 ID를 제거, $profile에서 볼 수있는 모든 ID를 추적 할 수 있습니다. 당신의 루프 실행이 완료되면 ID의 배열은 $profile에 있던 모든 ID를 가지고 있지만 $profile2됩니다

my @ids; 
foreach my $l (@$profile) { 
    my $id = $l->{ID}; 
    my $desc = $l->{DESCRIPTION}; 
    my $name = $l->{NAME}; 
    my $ver = $l->{VERSION}; 

    # save ids from $profile 
    push @ids, $id; 

    foreach my $i (@$profile2) { 
     my $id2 = $i->{ID}; 
     my $desc2 = $i->{DESCRIPTION}; 
     my $name2 = $i->{NAME}; 
     my $ver2 = $i->{VERSION}; 

     if ($id eq $id2) { 
      # remove elements that were in $profile2 
      @ids = grep { $_ != $id2 } @ids; 
      my $update = 'UPDATE PROFILE SET DESCRIPTION='."\'$desc\'".', NAME='."\'$name\'".', VERSION='."\'$ver\'".' WHERE ID='."\'$id\'".';'; 
      my $sth3 = $dbh2->prepare($update); 
      $sth3->execute; 
     } 
    } 
} 

# Now @ids is the array of all IDs in $profile, but not $profile2 
foreach my $id (@ids) { 
    # create insert 
}