我尝试在两个单独的数据库中使用两个单独的表,并将这些字段相互比较。我写了下面的代码来演示我遇到的问题,因为我无法复制我正在使用的代码。在下面的示例中,我使用的是一个数据库。在代码示例下面,我将提供每个表的转储。在任何情况下都有更好的描述。
reference_table保存original_table中列出的记录。我无法控制original_table的内容。获取这些记录后,在original_table中编辑信息的人员可以更新任何字段,或者他们可以彻底删除该条目。
我的目标是,当回到original_table时,将字段状态更新为禁用,其中original_table中的任何字段不再与我在reference_table中的记录匹配。查看转储时,您会注意到一个名为unique_id的字段。这是original_table的id。
我遇到的两个主要问题是使用reference_table的ident来更新reference_table中的状态,并正确地看到表的相似之处。
#!/usr/bin/perl
use strict;
use DBI;
use Data::Dumper;
my $dbh = DBI->connect('dbi:mysql:test','user','password',
{
RaiseError => 1,
AutoCommit => 0
}
) || die "Database connection not made: $DBI::errstr";
my $sql = "SELECT * FROM original_table";
my $sth = $dbh->prepare( $sql ) or die $dbh->errstr;
$sth->execute() or die $sth->errstr;
my @original;
while (my $data = $sth->fetchrow_hashref()){
push(@original, $data);
}
my $sql = "SELECT * FROM reference_table";
my $sth = $dbh->prepare( $sql ) or die $dbh->errstr;
$sth->execute() or die $sth->errstr;
my @reference;
while (my $data = $sth->fetchrow_hashref()){
push(@reference, $data);
}
foreach (sort keys @reference){
unless (exists $original[$_]){
my $sql = "UPDATE reference_table SET status = 'd' WHERE ident $reference[ident]";
my $sth = $dbh->prepare( $sql ) or die $dbh->errstr;
$sth->execute() or die $sth->errstr;
print "$_: not found in Remote Group\n";
next;
}
if ($reference[$_] eq $original[$_]){
print "$_: values are equal\n"
}else{
print "$_: values are not equal\n";
}
}
$dbh->disconnect();
代码产生以下结果:
0: values are not equal
1: values are not equal
10: values are not equal
11: not found in Remote Group
2: values are not equal
3: values are not equal
4: values are not equal
5: values are not equal
6: values are not equal
7: values are not equal
8: values are not equal
9: values are not equal
每张桌子的转储:
@original
$VAR1 = [
{
'timezone' => 'tz_001',
'status' => 'a',
'full_name' => 'name_001',
'ident' => '1'
},
{
'timezone' => 'tz_002',
'status' => 'a',
'full_name' => 'name_002',
'ident' => '2'
},
{
'timezone' => 'tz_003',
'status' => 'a',
'full_name' => 'name_003',
'ident' => '3'
},
{
'timezone' => 'tz_004',
'status' => 'a',
'full_name' => 'name_004',
'ident' => '4'
},
{
'timezone' => 'tz_005',
'status' => 'a',
'full_name' => 'name_005',
'ident' => '5'
},
{
'timezone' => 'tz_006',
'status' => 'a',
'full_name' => 'name_006',
'ident' => '6'
},
{
'timezone' => 'tz_007',
'status' => 'a',
'full_name' => 'name_007',
'ident' => '7'
},
{
'timezone' => 'tz_008',
'status' => 'a',
'full_name' => 'name_008',
'ident' => '8'
},
{
'timezone' => 'tz_009',
'status' => 'a',
'full_name' => 'name_009',
'ident' => '9'
},
{
'timezone' => 'tz_010',
'status' => 'a',
'full_name' => 'name_010',
'ident' => '10'
},
{
'timezone' => 'tz_011',
'status' => 'a',
'full_name' => 'name_011',
'ident' => '11'
}
];
@Reference
$VAR1 = [
{
'timezone' => 'tz_001',
'status' => 'a',
'full_name' => 'name_001',
'ident' => '1',
'unique_id' => '1'
},
{
'timezone' => 'tz_002',
'status' => 'a',
'full_name' => 'name_002',
'ident' => '2',
'unique_id' => '2'
},
{
'timezone' => 'tz_003',
'status' => 'a',
'full_name' => 'name_003',
'ident' => '3',
'unique_id' => '3'
},
{
'timezone' => 'tz_004',
'status' => 'a',
'full_name' => 'name_004',
'ident' => '4',
'unique_id' => '4'
},
{
'timezone' => 'tz_005',
'status' => 'a',
'full_name' => 'name_122',
'ident' => '5',
'unique_id' => '5'
},
{
'timezone' => 'tz_006',
'status' => 'a',
'full_name' => 'name_006',
'ident' => '6',
'unique_id' => '6'
},
{
'timezone' => 'tz_007',
'status' => 'a',
'full_name' => 'name_007',
'ident' => '7',
'unique_id' => '7'
},
{
'timezone' => 'tz_008',
'status' => 'a',
'full_name' => 'name_008',
'ident' => '8',
'unique_id' => '8'
},
{
'timezone' => 'tz_009',
'status' => 'a',
'full_name' => 'name_009',
'ident' => '9',
'unique_id' => '9'
},
{
'timezone' => 'tz_010',
'status' => 'a',
'full_name' => 'name_010',
'ident' => '10',
'unique_id' => '10'
},
{
'timezone' => 'tz_011',
'status' => 'a',
'full_name' => 'name_011',
'ident' => '11',
'unique_id' => '11'
},
{
'timezone' => 'tz_012',
'status' => 'a',
'full_name' => 'name_012',
'ident' => '12',
'unique_id' => '12'
}
];
如果您有其他问题,请与我们联系。非常感谢任何帮助。
答案 0 :(得分:5)
"UPDATE reference_table SET status = 'd' WHERE ident $reference[ident]"
问题在于$reference[ident]
。您正在尝试访问由裸字ident
索引的数组元素,但这不起作用。
要更正此问题,请使用适当的索引,例如$_
。下一个问题是@reference
是一个hashrefs数组。我假设你想在hashref中使用ident
字段。然后:$reference[$_]{ident}
。
我还建议您使用占位符来避免转义时可能出现的问题:
my $sql = "UPDATE reference_table SET status = 'd' WHERE ident ?";
my $sth = $dbh->prepare($sql) or die $dbh->errstr;
$sth->execute($reference[$_]{ident}) or die $sth->errstr;
您的代码存在一些剩余的样式问题,但这应该可以帮助您。
答案 1 :(得分:3)
您正在使用字符串比较运算符eq
来尝试与哈希引用进行比较。
$reference[$_] eq $original[$_]
哈希引用的“字符串化”是类似HASH(0xdeadbeef)
的字符串,因此除非$reference[$_]
和$original[$_]
引用完全相同的内存,否则这将始终为false。
即使比较所有键和值也无法满足您的需求,因为$reference[$_]
哈希引用包含键unique_id
而$original[$_]
不包含。
更加个性化的解决方案如下:
if (equivalent($reference[$_],$original[$_]) {
print "$_: values are equal\n"
} else {
print "$_: values are not equal\n";
}
sub equivalent {
my ($hash1, $hash2) = @_;
return $hash1->{timezone} eq $hash2->{timezone} &&
$hash1->{status} eq $hash2->{status} &&
$hash1->{full_name} eq $hash2->{full_name} &&
$hash1->{ident} eq $hash2->{ident} &&
}