كيف يمكنني التحقق مما إذا كان استعلام قاعدة البيانات سيرجع النتائج؟

StackOverflow https://stackoverflow.com/questions/290133

  •  08-07-2019
  •  | 
  •  

سؤال

يستخدم موقعنا الإلكتروني لغة Perl لتوفير آلية بسيطة لموظفي الموارد البشرية لدينا لنشر الوظائف الشاغرة على موقعنا.لقد تم تطويره من قبل طرف ثالث، ولكن تم التواصل معهم منذ فترة طويلة، وللأسف ليس لدينا أي مهارات في لغة Perl داخل الشركة.هذا ما يحدث عندما يتحايل موظفو التسويق على فريق تكنولوجيا المعلومات الداخلي لديهم!

أحتاج إلى إجراء تغيير بسيط على هذا التطبيق.حاليًا، صفحة الوظائف الشاغرة تقول "لدينا حاليًا الوظائف الشاغرة التالية:"، بغض النظر عما إذا كان هناك أي وظائف شاغرة!لذلك نريد تغييره بحيث يتم عرض هذا الخط فقط في الأوقات المناسبة.

من الواضح أنه يمكنني أن أبدأ في تعلم القليل من لغة Perl، لكننا نخطط بالفعل لإنشاء موقع بديل، ومن المؤكد أنه لن يستخدم لغة Perl.وبما أن الحل سيكون تافهًا بالنسبة لأولئك الذين يمتلكون هذه المهارات، فقد فكرت في أن أطلب بعض المساعدة المركزة.

فيما يلي بداية الإجراء الذي يسرد الوظائف الشاغرة.

sub list {
  require HTTP::Date;
  import HTTP::Date;

  my $date = [split /\s+/, HTTP::Date::time2iso(time())]->[0];

  my $dbh = DBI->connect($dsn, $user, $password)
    || die "cannot connect to $database: $!\n";

  my $sql = <<EOSQL;
SELECT * FROM $table where expiry >= '$date' order by expiry
EOSQL

  my $sth = $dbh->prepare($sql);
  $sth->execute();


  while (my $ref = $sth->fetchrow_hashref()) {
    my $temp  = $template;
    $temp     =~ s#__TITLE__#$ref->{'title'}#;

    my $job_spec = $ref->{'job_spec'};

...etc...

الخط الرئيسي هو while (my $ref = $sth->fetchrow_hashref()) {.أعتقد أن هذا يقول "بينما يمكنني سحب وظيفة شاغرة أخرى من مجموعة السجلات التي تم إرجاعها...".إذا قمت بوضع بيان الطباعة الخاص بي قبل هذا السطر، فسيتم عرضه دائمًا؛بعد هذا السطر ويتكرر مع كل منصب شاغر.

كيف يمكنني تحديد أن هناك بعض الوظائف الشاغرة سيتم عرضها، دون التنقل قبل الأوان عبر مجموعة السجلات التي تم إرجاعها؟

يمكنني دائمًا نسخ الكود داخل حلقة while ووضعه ضمن عبارة if() (التي تسبق حلقة while) والتي ستتضمن أيضًا عبارة print الخاصة بي.لكنني أفضل اتباع النهج الأبسط فقط If any records then print "We currently have.." line.لسوء الحظ، ليس لدي أدنى فكرة عن ترميز حتى هذا السطر البسيط.

انظر، لقد أخبرتك أنها مشكلة تافهة، حتى مع الأخذ في الاعتبار تفسيري المتخبط!

تيا

كريس

هل كانت مفيدة؟

المحلول

وهناك طريقة بسيطة حقا ستكون كما يلي:

$sth->execute();

my $first = 1;
while (my $ref = $sth->fetchrow_hashref()) {
    if( $first ) {
        print "We currently have the following vacancies:\n";
        $first = 0;
    }
    my $temp  = $template;
    ...
}
if( $first ) {
    print "No vacancies found\n";
}

نصائح أخرى

إذا كنت تستخدم الخلية، و "صفوف" الأسلوب يعمل على ما يرام:

$sth->execute();

if($sth->rows) {
  print "We have data!\n";
}

while(my $ref = $sth->fetchrow_hashref()) {
...
}

والأسلوب، وبعض المحاذير، يتم توثيقها في التفاصيل واسعة في "perldoc DBI". تبدأ دائما مع "perldoc".

هذا ليس سؤالًا يتعلق بـ Perl بقدر ما هو سؤال يتعلق بقاعدة البيانات، ولا توجد طريقة جيدة لمعرفة عدد النتائج التي لديك حتى تحصل عليها.لديك خياران هنا:

  1. قم بإجراء استعلام يقوم بإجراء "select count(*)" لمعرفة عدد الصفوف الموجودة، ثم استعلام آخر للحصول على الصفوف الفعلية أو
  2. قم بالاستعلام وقم بتخزين النتائج في التجزئة، ثم قم بحساب عدد الإدخالات الموجودة في التجزئة، ثم قم بالاطلاع على التجزئة وطباعة النتائج.

على سبيل المثال، من أعلى رأسي:

my @results = ();
while (my $ref = $sth->fetchrow_hashref()) {
   push @results, $ref;
}

if ($#results == 0) {
  ... no results
} else {
  foreach $ref (@results) {
    my $temp = $template;
    ....
 }

ولأن الجميع يريد تحسين بعيدا الاختبارات المتكررة لما إذا كان قد تم طباعة رأس في حل غرايم، وأنا أقدم هذا الاختلاف بسيط على ذلك:

$sth->execute();

my $ref = $sth->fetchrow_hashref();
if ($ref) {
  print "We currently have the following vacancies:\n";
  while ($ref) {
    my $temp  = $template;
    ...
    $ref = $sth->fetchrow_hashref();
  }
} else {
    print "No vacancies found\n";
}

ومنذ الاستعلام الخاص بك هو تحديد ، أو لا يمكن الاستفادة من <لأ href = "http://search.cpan.org/~timb/DBI-1.631/DBI.pm#rows" يختلط = "نوفولو"> <م> الصفوف أو من القيمة التي تم إرجاعها من قبل في <م> تنفيذ نفسها.

ولكن، يمكنك قبل نحصي عدد الصفوف (أي شواغر) الاستعلام الخاص بك سوف تختار بإضافة استفسار آخر ... شيء من هذا القبيل:

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?";
$sth = $dbh->prepare($query);
$sth->execute($date);
$numVacancies = $numinfo->fetchrow_arrayref()->[0];

# Debug:
print "Number of vacancies: " . $numVacancies . "\n";

if ( $numVacancies == 0 ) { # no vacancy found...
    print "No vacancies found!\n";
}
else { # at least a vacancy has been found...
    print "We currently have the following vacancies:\n";

    # Retrieve the vacancies:
    my $sql = "SELECT * FROM $table where expiry >= '$date' ORDER BY expiry";
    my $sth = $dbh->prepare($sql);
    $sth->execute();

    ...
}

وأو، على نحو مماثل، بدلا من "إعداد" و <م> "تنفيذ" الاستعلام ثم استخدم "fetchrow_array" ، يمكنك أن تفعل كل شيء في مكالمة واحدة باستخدام <م> selectrow_array :

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?"; 
my $numVacancies = $dbh->selectrow_array($query, undef, $date);

# Debug:
print "Number of vacancies: " . $numVacancies . "\n";

ونفس الشيء ينطبق أيضا على <م> selectall_arrayref :

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?";
my $numVacancies = $dbh->selectall_arrayref($query, {Slice => {}}, $date);

# Debug:
print "Number of vacancies: " . @$numVacancies[0]->{rows} . "\n";

ولكن، إذا كنت تستخدم selectrow_array أو <م> selectall_arrayref ، يمكنك أيضا استرداد عدد من الوظائف الشاغرة مباشرة من نتيجة الاستعلام الأصلي:

# Retrieve the vacancies:
my $sql = "SELECT * FROM $table where expiry >= ? ORDER BY expiry";
my $vacancies = $dbh->selectall_arrayref($sql, {Slice => {}}, $date);

# Debug:
print "Number of vacancies: " . scalar @{$vacancies} . "\n";

وقليلا بطريقة أكثر كفاءة (تجنب مشروطة داخل الحلقة)، إذا كنت لا تمانع في ذلك تغيير طريقة الصفحة هو الإخراج قليلا (في كل مرة بدلا من صف واحد في وقت واحد) التي يمكن أن تجعل متغير عقد الانتاج قبل الحلقة:

my $output = '';

وبعد ذلك داخل الحلقة، تغيير أي بيان الطباعة لتبدو مثل هذا:

$output .= "whatever we would have printed";

وثم بعد الحلقة:

if ($output eq '')
{
  print 'We have no vacancies.';
}
else
{
  print "We currently have the following vacancies:\n" . $output;
}

وأضيف استفسار آخر .. شيء من هذا القبيل:

# count the vacancies    
$numinfo = $dbh->prepare("SELECT COUNT(*) FROM $table WHERE EXPIRY >= ?");
$numinfo->execute($date);
$count = $numinfo->fetchrow_arrayref()->[0];

# print a message
my $msg = '';
if   ($count == 0) $msg = 'We do not have any vacancies right now';
else               $msg = 'We have the following vacancies';
print($msg);
use Lingua::EN::Inflect 'PL';

$sth->execute();
my $results = $sth->fetchall_arrayref( {}, $max_rows );

if (@$results) {
    print "We currently have the following ", PL("vacancy",scalar @$results), ":\n";

    for my $ref (@$results) {
        ...
    }
}

ويقول perldoc DBI:

 For a non-"SELECT" statement, "execute" returns the number of rows
 affected, if known. If no rows were affected, then "execute"
 returns "0E0", which Perl will treat as 0 but will regard as true.

وهكذا فإن الجواب هو للتحقق من قيمة الإرجاع $ sth-> تنفيذ ():

 my $returnval = $sth->execute;
 if (defined $returnval && $returnval == 0) {
     carp "Query executed successfully but returned nothing";
     return;
 }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top