문제

Perl로 작은 "DBQuery" 함수를 작성하여 SQL 문을 보내고 다시 받는 단일 라이너와 해시 배열을 가질 수 있습니다.레코드세트.그러나 Perl 구문(및 아마도 이상한 포인터/참조 문제)에 문제가 발생하여 데이터베이스에서 가져오는 해시의 정보를 압축할 수 없습니다.아래 샘플 코드는 문제를 보여줍니다.

다음 구문을 사용하면 배열 내부의 해시에서 "Jim" 데이터를 가져올 수 있습니다.

print $records[$index]{'firstName'}

"짐"을 반환합니다.

하지만 배열의 해시 레코드를 자체 해시 변수에 먼저 복사하면 이상하게도 해당 해시에 있는 데이터에 더 이상 액세스할 수 없습니다.


    %row = $records[$index];
    $row{'firstName'};

""(공백)을 반환합니다.

다음은 문제를 보여주는 전체 샘플 코드입니다.도움을 주시면 감사하겠습니다.


my @records = (
   {'id' => 1, 'firstName' => 'Jim'},
   {'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();

$numberOfRecords = scalar(@records);
print "number of records: " . $numberOfRecords . "\n";
for(my $index=0; $index < $numberOfRecords; $index++) {

   #works
   print 'you can print the records like this: ' . $records[$index]{'firstName'} . "\n";

   #does NOT work
   %row = $records[$index];
   print 'but not like this: ' . $row{'firstName'} . "\n";

} 
도움이 되었습니까?

해결책

중첩된 데이터 구조에 해시가 포함되어 있습니다. 참조, 해시가 아닙니다.

# Will work (the -> dereferences the reference)
$row = $records[$index];
print "This will work: ", $row->{firstName}, "\n";

# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print "This will work: ", $row{firstName}, "\n";

깊은 Perl 데이터 구조를 본 적이 있다면 다음을 사용하여 인쇄하면 도움이 될 수 있습니다. 데이터::덤퍼 사람이 읽을 수 있는(그리고 Perl이 구문 분석할 수 있는) 형식으로 인쇄합니다.

다른 팁

해시 배열은 실제로 해시를 포함하지 않지만 오히려 참고자료 해시로.이 줄은:

%row = $records[$index];

하나의 항목으로 %row를 할당합니다.핵심은 스칼라:

   {'id' => 1, 'firstName' => 'Jim'},

이는 해시에 대한 참조이며 값은 비어 있습니다.

당신이 정말로 하고 싶은 것은 이것이다:

$row = $records[$index];
$row->{'firstName'};

그렇지 않으면:

$row = %{$records[$index];}
$row{'firstName'};

다른 사람들은 해시와 해시 참조에 대해 논평했습니다.언급해야 할 또 다른 사항은 DBQuery 기능입니다. DBI에 이미 내장된 작업을 수행하려는 것 같습니까?귀하의 질문을 올바르게 이해한다면 다음과 같은 것을 복제하려고하는 것입니다. selectall_arrayref:

이 유틸리티 메소드는 "prepare", "execute" 및 "fetchall_arrayref"를 단일 호출로 결합합니다.가져온 데이터의 각 행에 대한 배열(또는 해시, 아래 참조)에 대한 참조를 포함하는 배열에 대한 참조를 반환합니다.

위의 멋진 답변에 추가하기 위해 항상, 항상, 항상(예, 세 개의 "항상") 코드 상단에 "경고 사용"을 사용해야 한다는 점을 추가하겠습니다.그렇게 했다면 "-e 라인 1에서 짝수 크기의 목록이 예상되는 참조를 찾았습니다."라는 경고를 받았을 것입니다.

실제로 배열에 있는 것은 해시가 아니라 해시 참조입니다.이 개념을 이해하지 못한다면 읽어볼 가치가 있을 것입니다. 펄레프 선적 서류 비치.

당신이해야 할 해시를 얻으려면

my %hash = %{@records[$index]};

예.

my @records = (
     {'id' => 1, 'firstName' => 'Jim'}, 
     {'id' => 2, 'firstName' => 'Joe'}
  );

  my %hash = %{$records[1]};

  print $hash{id}."\n";

하지만.학문적 목적이 아니라면 왜 이런 일을 하고 싶어하는지 잘 모르겠습니다.그렇지 않으면 DBI 모듈에서 fetchall_hashref/fetchall_arrayref를 사용하거나 Class::DBI와 같은 것을 사용하는 것이 좋습니다.

또한 사용하기 좋은 Perl 관용구는 다음과 같습니다.

for my $rowHR ( @records ) {
   my %row = %$rowHR; 
   #or whatever...
}

목록을 반복합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top