【问题标题】:How to pass a hash to a sub?如何将哈希传递给子?
【发布时间】:2011-08-15 14:59:54
【问题描述】:

在我的 perl“脚本”中,我正在收集数据并构建哈希图。 hashmap键代表字段名称,值代表我要插入相应字段的值。

hashmap 被构建,然后传递给 saveRecord() 方法,该方法应该构建 SQL 查询并最终执行它。

这里的想法是更新数据库一次,而不是每个字段一次(有很多字段)。

问题:我无法将 hashmap 传递给 sub,然后将字段和值从 hashmap 中拉出。此时我的键和值是空白的。我怀疑数据在传递给潜艇的过程中丢失了。

脚本的输出表明没有键和值。

需要帮助以某种方式将数据传递给 sub,以便我将其拉回,如图所示 - 使用 join()

谢谢!

代码sn-p:

for my $key (keys %oids) {
        $thisField = $key;
        $thisOID = $oids{$thisField};
        # print "loop: thisoid=$thisOID field=$thisField\n";

        # perform the SNMP query.
        $result = getOID ($thisOID);
        # extract the information from the result.
        $thisResult = $result->{$thisOID};

        # remove quotation marks from the data value, replace them with question marks.
        $thisResult =~ s/\"|\'|/\?/g;

        # TODO: instead of printing this information, pass it to a subroutine which writes it to the database (use an update statement).
        # printf "The $thisField for host '%s' is '%s'.\n", $session->hostname(), $result->{$thisOID};

        # add this key/value pair to the mydata hashmap.
        $mydata{$thisField} = $thisResult;

        # print "$thisField=$thisResult\n";
}


# write one record update for hashmap %mydata.
saveRecord (%mydata);


# write all fields to database at once...
sub saveRecord ($) {
        my $refToFields=shift;


        my @fieldlist = keys %$refToFields;
        my @valuelist = values %$refToFields;
        my $sql = sprintf ("INSERT INTO mytable (%s) VALUES (%s)",join(",",@fieldlist), join(",",@valuelist) );

        # Get ID of record with this MAC, if available, so we can perform SQL update
        my $recid = getidbymac ($MAC);

        print "sql=$sql\n";
    # TODO: use an insert or an update based on whether recid was available...
        # TODO: ID available, update the record
        # TODO: ID not available, insert record let ID be auto assigned.
}

【问题讨论】:

  • 一般情况下,不要使用子程序原型。它们不像其他语言那样工作。大多数情况下,它们的存在是为了让模块作者可以复制内置函数的接口。有关更多信息,请参阅 perldoc perlsub。 perldoc.perl.org/perlsub.hmtl

标签: sql perl hash parameter-passing dbi


【解决方案1】:

我稍微清理了你的代码。您的主要问题是在调用您的子时没有使用参考。另请注意已清理的注释正则表达式:

代码:

use strict;
use warnings;

# $thisResult =~ s/["']+/?/g;
my %mydata = ( 'field1' => 12, 'field2' => 34, );

saveRecord (\%mydata); # <-- Note the added backslash

sub saveRecord {
    my $ref = shift;
    my $sql = sprintf "INSERT INTO mytable (%s) VALUES (%s)",
        join(',', keys %$ref),
        join(',', values %$ref);
    print "sql=$sql\n";
}

输出:

sql=INSERT INTO mytable (field1,field2) VALUES (12,34)

【讨论】:

  • 非常好,干净。谢谢 TLP!
  • 这是一个很好的重写。如果您解释了为什么要进行更改,那将是一个很好的答案。由于子参数列表扁平化,您传递了一个引用。你放弃原型是因为它们在这里不受欢迎。您用字符类替换了替代,因为它更易于阅读。您删除了不需要的转义,因为它们也是不需要的。我没有足够的空间来完全解释每个项目,但至少现在有一些好奇的搜索词。
  • @dao 好点。不过,我认为代码本身就很能说明问题。
猜你喜欢
  • 2011-06-21
  • 2020-06-14
  • 2011-02-01
  • 2013-09-27
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多