我有這個回圈,我在其中填充記錄并嘗試將其推送到陣列:
while (@data = $sth->fetchrow_array()) {
$rec->{'article_id'} = $data[0];
$rec->{'category_id'} = $data[1];
$rec->{'category_name'} = $data[2];
$rec->{'author_id'} = $data[3];
$rec->{'headline'} = $data[4];
$rec->{'teaser'} = $data[5];
$rec->{'author_name'} = $data[7];
push @article_data, $rec;
}
然而,當這個回圈完成時,@array_data 只包含 $rec 中的最后一個元素。我每次都通過回圈列印 $rec ,并且它被正確填充,每次都有不同的值。但是,@array_data 看起來像這樣:
$VAR1 = {
'author_name' => 'Equity Research',
'author_id' => '631459560',
'teaser' => 'Barnes' (B) first-quarter 2022 revenues increase 4% year over year.',
'article_id' => '16608',
'category_name' => 'Analyst Blog : Earnings Article',
'category_id' => '298',
'headline' => 'Barnes Group (B) Q1 Earnings & Revenues Surpass Estimates'
};
$VAR2 = $VAR1;
$VAR3 = $VAR1;
$VAR4 = $VAR1;
這是回圈中從資料庫中檢索到的最后一個元素。為什么不將每個專案推入@article_data 中的不同元素?
uj5u.com熱心網友回復:
在回圈開始時,添加$rec = {};.
當前$rec在整個回圈中保持相同的物體,您只會在每次迭代中覆寫給定鍵集的值。因此,您最終會得到一組相同的副本。
uj5u.com熱心網友回復:
您已經得到了兩個可行的答案,我想我會詳細說明各種解決方案。
while (@data = $sth->fetchrow_array()) {
您真正應該在這里做的是使用詞法范圍的回圈變數,例如my @data. 它是一種廣泛使用的 Perl 習語,可以防止許多頭痛。
在您的錯誤發生的下一行中,這個習語可以拯救您:
$rec->{'article_id'} = $data[0];
由于您沒有創建詞法變數,因此這些哈希鍵只會在每次回圈迭代時被覆寫,就像您使用常規標量變數一樣:
$article_id = $data[0];
然而,一個簡單的my宣告會為你省去所有的悲傷:
my $rec; # create a fresh variable
$rec->{'article_id'} = $data[0];
但還有更多。您正在使用對哈希的參考作為將資料放入陣列的工具,但我們并不真正需要該工具。考慮一下:
push @article_data, { # this creates a new anonymous hash ref
article_id => $data[0], # you can insert comments here (*)
category_id => $data[1],
.... }; # end of hash ref
我們可以使用 動態創建臨時哈希參考{ ... }。這些大括號內的所有內容都將被視為哈希鍵和值對。
這個解決方案很有吸引力,因為它很冗長——您可以非常清楚地看到所有內容,甚至可以為不同的值添加注釋 (*)——但有時您喜歡它快速而簡潔。特別是如果您有非常大的資料結構。在這種情況下,您可以使用哈希切片。這將節省您輸入陣列索引的作業。
my @keys = qw(article_id category_id category_name author_id
headline teaser author_name); # this can be place elsewhere in your code
my %rec;
@rec{ @keys } = @data; # short and simple assignment
push @article_data, \%rec;
如果你絕對喜歡使用哈希參考,你可以這樣做
my $rec;
@{ $rec }{ @keys } = @data;
push @article_data, $rec;
最后,我確信 Perl DBI提供了一個特性,您可以在其中為列分配名稱,或保持現有名稱從資料庫繼承。例如fetchrow_hashref. 它將獲取所有行,并可能通過fetchall_arrayref一個函式呼叫為您完成所有這些作業。查一下。
uj5u.com熱心網友回復:
您只有一個哈希,并且$rec是對該哈希的參考。回圈的每一次傳遞,您都會將該參考的副本添加到陣列中。因此,您最終會多次參考一個哈希。
但是你想要多個哈希。每行一個。您可以使用my %rec;或{}創建
while ( my @data = $sth->fetchrow_array() ) {
my %rec = (
article_id => $data[ 0 ],
category_id => $data[ 1 ],
category_name => $data[ 2 ],
author_id => $data[ 3 ],
headline => $data[ 4 ],
teaser => $data[ 5 ],
author_name => $data[ 7 ],
);
push @article_data, \%rec;
}
或者
while ( my @data = $sth->fetchrow_array() ) {
push @article_data, {
article_id => $data[ 0 ],
category_id => $data[ 1 ],
category_name => $data[ 2 ],
author_id => $data[ 3 ],
headline => $data[ 4 ],
teaser => $data[ 5 ],
author_name => $data[ 7 ],
};
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/470778.html
