【问题标题】:Bareword "ident" not allowed while "strict subs" in use at cgi-bin/test.pl在 cgi-bin/test.pl 中使用“strict subs”时不允许使用裸词“ident”
【发布时间】:2014-04-04 22:14:00
【问题描述】:

我试图在两个单独的数据库中获取两个单独的表,然后将这些字段相互比较。我编写了以下代码来演示我遇到的问题,因为我无法复制我正在使用的代码。在下面的示例中,我使用一个数据库。在代码示例下面,我将提供每个表的转储。无论如何都要有更好的描述。

reference_table 保存 original_table 中列出的记录。我无法控制 original_table 的内容。获取这些记录后,original_table 中信息的编辑人员可以更新任何字段,也可以直接删除该条目。

我的目标是,当返回 original_table 时,将字段状态更新为禁用,其中 original_table 中的任何字段不再匹配我在 reference_table 中的记录。查看转储时,您会注意到一个名为 unique_id 的字段。这是 original_table 的 id。

我遇到的两个主要问题是使用reference_table 的标识来更新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'
          }
        ];

如果您还有其他问题,请告诉我。非常感谢任何帮助。

【问题讨论】:

    标签: mysql arrays perl loops if-statement


    【解决方案1】:
    "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;
    

    您的代码还存在一些样式问题,但这应该能让您继续前进。

    【讨论】:

    • 谢谢,这对您很有帮助。
    【解决方案2】:

    您正在使用字符串比较运算符eq 尝试与哈希引用进行比较。

    $reference[$_] eq $original[$_]
    

    哈希引用的“字符串化”是一个类似于HASH(0xdeadbeef) 的字符串,因此除非$reference[$_]$original[$_] 引用完全相同的内存,否则这将始终为假。

    即使比较所有键和值也不会给您想要的结果,因为 $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} &&
    }
    

    【讨论】:

    • 谢谢,这对您很有帮助。
    • key 的 arg 1 类型必须是“@array)”附近的散列(不是私有数组)
    • 这适用于我的家庭服务器,但不适用于生产服务器。我得到的错误是,键的 arg 1 类型必须是“@reference”附近的散列(不是私有数组)这是用于包含 if 语句的循环。除非(排序键@reference){
    • keys ARRAY 语法仅从 Perl v5.14 开始可用,通常无用。不要说foreach (keys @array) {...},而是说foreach (0..$#array) {...}
    猜你喜欢
    • 2019-01-17
    • 2019-06-05
    • 2012-11-11
    • 2013-11-03
    • 2016-02-12
    • 1970-01-01
    • 2017-08-20
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多