سؤال

أرغب في كتابة وظيفة "DBQuery" صغيرة بلغة Perl حتى أتمكن من الحصول على سطر واحد يرسل عبارة 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];

يعين صفًا واحدًا بإدخال واحد.المفتاح هو العددية:

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

وهو إشارة إلى التجزئة، في حين أن القيمة فارغة.

ما تريد فعله حقًا هو هذا:

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

او اخرى:

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

وقد علق آخرون على التجزئة مقابل التجزئة.هناك شيء آخر أشعر أنه يجب ذكره وهو وظيفة DBQuery الخاصة بك - يبدو أنك تحاول القيام بشيء مضمن بالفعل في DBI؟إذا فهمت سؤالك بشكل صحيح، فأنت تحاول تكرار شيء من هذا القبيل Selectall_arrayref:

تجمع طريقة الأداة المساعدة هذه بين "التحضير" و"التنفيذ" و"fetchall_arrayref" في مكالمة واحدة.تقوم بإرجاع مرجع إلى مصفوفة تحتوي على مرجع إلى مصفوفة (أو تجزئة، انظر أدناه) لكل صف من البيانات التي تم جلبها.

للإضافة إلى الإجابات الرائعة أعلاه، اسمحوا لي أن أضيف أنه يجب عليك دائمًا، دائمًا، دائمًا (نعم، ثلاثة "دائمًا") استخدام "استخدام التحذيرات" في الجزء العلوي من التعليمات البرمجية الخاصة بك.إذا قمت بذلك، فستحصل على التحذير "تم العثور على المرجع حيث كانت القائمة ذات الحجم الزوجي متوقعة في -e السطر 1."

ما لديك بالفعل في صفيفك هو تجزئة، وليس تجزئة.إذا كنت لا تفهم هذا المفهوم، فربما يستحق قراءة هذا المقال perlref توثيق.

للحصول على التجزئة ما عليك القيام به

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

على سبيل المثال.

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

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

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

بالرغم من.لست متأكدًا من سبب رغبتك في القيام بذلك، إلا إذا كان ذلك لأغراض أكاديمية.بخلاف ذلك، أوصي باستخدام fetchall_hashref/fetchall_arrayref في وحدة DBI أو استخدام شيء مثل Class::DBI.

لاحظ أيضًا أن لغة Perl الجيدة التي يجب استخدامها هي

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

للتكرار من خلال القائمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top