-4

您有一张名为 Pets 的表格:

name     age     pet
------------------------
Carol     25     null
Stean     23     cat
Mel       24     dog
Rich      24     rabbit

在服务器 mydbserver 上的 MySQL 数据库中,用户为“user”,密码为“password”。

请执行下列操作:

Class::DBI1)使用上述凭据 ( DBI.pm )创建与此数据库的连接。

2) 为表 Pets ( Pet.pm ) 创建一个类

3) 创建一个程序,打印 Pets 表中所有人的姓名,以及他/她按姓名和年龄排序的宠物种类(如果有的话)。

这是我写的代码......

#!/usr/bin/perl      
package Pet::DBI;
use DBI;
use strict;
use base 'Class::DBI';
Pet::DBI->set_db('Main','dbi:mysql:dname', 'user', 'password') 

or die $DBI::errstr "\n";
1;

package Pet::Pets;
use base 'Pet::DBI';
use strict;
use warning;
Pet::Pets->table('Pets');
Pet::Pets->columns(All => qw/name age pet/);
1;

use Pet::Pets;
my @pets = Pet::Pets->retrieve_all; 
for (sort {$a->name cmp $b->name} || {$a->age <=> $b->age}  @Pets) {
print "Name:".$_->name ' => '."Age". $_->age"\n";
}

1;
4

1 回答 1

1

基本上是对的,但是有一些小问题。

没有必要加载 DBI,Class::DBI 会为您处理。

您应该使用connection而不是set_db("Main", ...). set_db来自 Ima::DBI,像这样偷看引擎盖是不礼貌的(或必要的)。

虽然这没有直接记录在 Class::DBI 中(应该是),它继承自Ima::DBI,但无需检查 DBI 错误。 RaiseError 处于打开状态,如果连接失败,它将引发错误。

你有一个错字,use warning;而不是use warnings;.

除非您将三个文件拼接在一起以发布帖子,否则如果代码都在一个文件中,则1;语句不会执行任何操作。 use Pet::Pets将无法工作,因为没有Pet/Pets.pm文件。您不必使用已经在同一个文件中的类。

一般情况下,非必要尽量避免使用$_,太多东西可以悄悄使用或改变。相反,给 for 循环一个适当的变量,如for my $person.

sort只需要一个街区,但你基本上是正确的。它应该是sort { ($a->name cmp $b->name) || ($a->age <=> $b->age) } @Pets

为了避免将整个可能非常大的表读入内存,排序实际上应该在数据库中使用 an 完成,然后使用iteratorORDER BY name ASC, age ASC一次检索一行。不幸的是,retrieve_all不支持任何选项。您可以使用将任意 SQL 添加到基本 SELECT 的末尾。 然后您的数据将已经排序并且可以一次读取一行。 retrieve_from_sqlmy $all_people = Pet::Pets->retrieve_from_sql("ORDER BY name ASC, age ASC");while( my $person = $all_people->next ) { ... }

你缺少一个.in "Age". $_->age"\n"

数据库中的空值作为 undef 返回。您将要检查是否$_->pet已定义,如果不使用其他字符串,例如"no pet"或只是一个空白"".

您正在打印此人的年龄,问题询问他们的宠物。

否则,它应该工作。

但实际上,告诉给你这个作业的人不要再告诉人们使用 Class::DBI。如果他们愿意,他们可以给我发电子邮件,schwern@pobox.com。

于 2015-03-17T03:31:57.983 回答