2011-08-15 17 views
1

私のperlの "スクリプト"では、データを収集してハッシュマップを構築しています。ハッシュマップキーはフィールド名を表し、値は対応するフィールドに挿入する値を表します。サブにハッシュを渡すには?

ハッシュマップは作成され、SQLクエリを作成するはずのsaveRecord()メソッドに渡され、最終的には実行されます。

ここで考えているのは、フィールドごとに1回ではなく、1回だけデータベースを更新することです(多くのフィールドがあります)。

問題:ハッシュマップをサブに渡して、ハッシュマップからフィールドと値を引き出すのに問題があります。この時点で私のキーと値は空白です。私はデータがサブに渡されている間に失われていると思う。

スクリプトの出力では、キーと値がないことを示します。

図のように離れて引き戻せるように、データをサブに渡す必要があります。join()

ありがとうございます!

コードスニペット:

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. 
} 
+0

を、サブルーチンのプロトタイプを使用しないでください。他の言語と同じように機能しません。主に、モジュール作成者が組み込み関数のインターフェースを複製できるように存在します。詳細はperldoc perlsubを参照してください。 http://perldoc.perl.org/perlsub.hmtl – daotoad

答えて

8

私はあなたのコードを少しクリーンアップ。あなたの主な問題はあなたのサブを呼び出すときに参照を使用していませんでした。

コード:

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) 
+0

とても素敵で清潔です。ありがとうTLP! –

+0

あなたは大歓迎です。 – TLP

+1

これは良い書き換えです。なぜあなたがあなたが行った変更をしたのか説明したなら、大きな答えとなりました。サブ引数リストのフラット化のために参照を渡します。プロトタイプはここでは望ましくないので、あなたはそのプロトタイプを捨てます。あなたは、読むのが簡単なので、交替を文字クラスに置き換えました。不要なエスケープも削除したので、不要なエスケープを削除しました。私は各項目を完全に説明するためのコメントに余裕はないが、少なくとも今好奇心の強い検索用語がある。 – daotoad

関連する問題