Arrays Perl,如果不是在哈希数组中

Arrays Perl,如果不是在哈希数组中,arrays,perl,hashtable,Arrays,Perl,Hashtable,我试图编写代码,根据另一个数据库中的内容更新、插入和删除数据库中的行。这最终将根据其他标准自动发生。目标是使表完全相同。数据库复制不是一个选项 这个问题实际上不是关于MYSQL或DBI模块,而是关于比较两个阵列 我使用了fetchall\u arrayref({})来创建两个哈希数组 这是原始数据库表的数组示例,在我的代码中它是$profile: [ { DESCRIPTION => "Default", ID => 0, NAME => "Default", VERSI

我试图编写代码,根据另一个数据库中的内容更新、插入和删除数据库中的行。这最终将根据其他标准自动发生。目标是使表完全相同。数据库复制不是一个选项

这个问题实际上不是关于MYSQL或DBI模块,而是关于比较两个阵列

我使用了
fetchall\u arrayref({})
来创建两个哈希数组

这是原始数据库表的数组示例,在我的代码中它是
$profile

[
  { 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" },
]
[
  { 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" },
]
这是数据库表数组的一个示例,我希望与另一个类似,它在我的代码中是
$profile2

[
  { 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" },
]
[
  { 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位于两个表中的条目:

foreach my $l (@$profile) {
    my $id = $l->{ID};
    my $desc = $l->{DESCRIPTION};
    my $name = $l->{NAME};
    my $ver = $l->{VERSION};
    foreach my $i (@$profile2) {
        my $id2 = $i->{ID};
        my $desc2 = $i->{DESCRIPTION};
        my $name2 = $i->{NAME};
        my $ver2 = $i->{VERSION};
        if ($id eq $id2) {
                my $update = 'UPDATE PROFILE SET DESCRIPTION='."\'$desc\'".', NAME='."\'$name\'".', VERSION='."\'$ver\'".' WHERE ID='."\'$id\'".';';
                my $sth3 = $dbh2->prepare($update);
                $sth3->execute;
        }
    }
}
现在,我需要代码来查找
$profile
中的ID是否不在
$profile2
中,将该行插入
$profile2
的数据库表中(
my$insert='insert-into-profile(ID、版本、名称、描述)值('.'\'$ID\'.'''.'$ver\''.'.'.'''''.''$NAME\'''.'.'.'.'.'.'.'''''.'$desc;'.
)。我需要代码来检查ID是否在
$profile2
中,而不是
$profile
中,然后从
$profile2
数据库中删除该行(
my$update='delete from profile WHERE ID='。“\'$id2\'”;


感谢您的帮助。谢谢

您可以简单地跟踪从
$profile
中看到的所有ID,然后当您在
$profile2
中遇到相同的ID时,将该ID从阵列中删除。循环完成后,ID数组将具有
$profile
中的所有ID,但不具有
$profile2

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");
}
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
}
这个怎么样:

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'
          }
        ];
啊!不要使用“
””“$var.”“
!使用占位符或
$dbh->quote($var)