用于登录数据库并进行简单查询的 Perl 模块?
Perl module to log in database and do a simple query?
我似乎无法找出我的 .pm 文件和脚本的问题。我是 Perl 的新手。
我有一个名为 "project" 的 数据库,还有一个 table 名为 "mailing".
邮件 table 有 7 个条目,我想使用模块显示这些条目。
所以,我有这个自定义模块来登录数据库并进行查询。此模块的名称为 DB.pm
DB.pm 存储在我的 FEDORA 20 上 /root/mysql/GUI/DB.pm.
DB.pm定义如下:
package GUI::DB;
use strict;
use DBI;
use vars qw(@ISA @EXPORT);
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dbConnect query);
#
# dbConnect - connect to the database, get the database handle
#
sub dbConnect {
# Read database settings from config file:
print "Works";
my $dsn = "DBI:mysql:project";
my $dbh = DBI->connect( $dsn,
'root',
'mydatabasepassword',
{ RaiseError => 1 }
);
return $dbh;
}
#
# query - execute a query with parameters
# query($dbh, $sql, @bindValues)
#
sub query {
my $dbh = shift;
my $sql ="SELECT * FROM mailing";
my @bindValues = @_; # 0 or serveral parameters
my @returnData = ();
# issue query
my $sth = $dbh->prepare($sql); //**line number 39 that is giving** error
if ( @bindValues ) {
$sth->execute(@bindValues);
} else {
$sth->execute();
}
if ( $sql =~ m/^select/i ) {
while ( my $row = $sth->fetchrow_hashref ) {
push @returnData, $row;
}
}
# finish the sql statement
$sth->finish();
return @returnData;
}
1;
现在我想在我的脚本中使用这个模块。这是我试过的:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/root/mysql/';
use GUI::DB qw(dbConnect query);
dbConnect();
query();
这是我遇到的错误 -->
无法在 /root/mysql/GUI/DB.pm 第 39 行的未定义值上调用方法 "prepare"。
请帮我解决这个问题。我不确定如何进行。我猜这与参数传递有关。数据库没有问题。它在 CLI 中运行良好。
谢谢:)
_x_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X__X_X_X_X_X__X
直到这里解决了
_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X__X_X_X
进一步的问题是 SQL 命令不起作用。
在我的数据库的邮件 table 中,我有不同域的电子邮件 ID。
例如,一些 ID 是 xyz@gmail.com、12343@gmail.com、bae@yahoo.com 等等,我假设新的电子邮件 ID 将添加到邮件 tables每天都有不同的域名。
我正在尝试编写一个脚本来更新另一个 table,它按域名保存每天的电子邮件地址计数。这是我试过的:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/root/mysql/';
use 5.016;
use Data::Dumper;
use GUI::DB qw(dbConnect query);
my $data = dbConnect();
my @domain = query($data, "SELECT substr(addr,locate('\@',addr)+1) as maildomain, count (*) as mailcount FROM mailing GROUP BY maildomain ORDER BY mailcount DESC");
for my $key (@domain){
say Dumper ($key);
}
但是我收到一个错误,
您的 SQL 语法有误;检查与您的 MariaDB 服务器版本相对应的手册,了解在第 1 行 /root/mysql/GUI/DB.pm 第 44 行 /root/mysql/GUI/DB.pm line 44.
相同的 SQL 语句在 CLI 中没有问题。
任何帮助,将不胜感激。 :)
1) 你的错误是说这里 $dbh 是未定义的:
sub query {
my $dbh = shift;
...
# issue query
my $sth = $dbh->prepare($sql); #<***LOOK HERE***
...这意味着此处必须未定义 $dbh:
sub query {
my $dbh = shift; #<***LOOK HERE***
...
# issue query
my $sth = $dbh->prepare($sql);
2) 让我们看看为什么。您的 dbConnect() 方法 returns $dbh:
sub dbConnect {
# Read database settings from config file:
print "Works";
my $dsn = "DBI:mysql:project";
my $dbh = DBI->connect(
$dsn,
'root',
'mydatabasepassword',
{ RaiseError => 1 }
);
return $dbh; #<***LOOK HERE*****
}
3) 但是,您可以这样调用 dbConnect():
dbConnect();
因为您从未在任何地方保存 return 值,$dbh 被丢弃。
4) 此外,您可以这样调用 query():
query();
然而,您这样定义了 query():
sub query {
my $dbh = shift;
query() sub 认为第一个参数将是数据库句柄——但您没有使用任何参数调用 query()。
您需要这样做:
my $data_base_handle = dbConnect();
my @results = query($data_base_handle);
#do something with @results
回复评论:
I printed @results, this is what I see HASH(0x1d05be8)
HASH(0x1d05ba0) HASH(0x1d05b58) HASH(0x1d05b10) HASH(0x1d05ac8)
HASH(0x1d05a80) HASH(0x1d05a38)
您写道:
my $row = $sth->fetchrow_hashref;
...这要求 DBI return 每行作为对散列的引用。然后你写道:
push @returnData, $row;
...将每个散列引用推入一个数组。所以 query() return 是一个散列引用数组。符号 HASH(0x1d05be8)
是打印散列引用时 perl 输出的内容。
如果您想查看这些哈希值中的内容,请执行以下操作:
use 5.016; #enable say()
use Data::Dumper;
...
...
for my $href (@results) {
say Dumper($href);
}
要访问哈希引用中的数据,您可以这样做:
use strict;
use warnings;
use 5.016;
use Data::Dumper;
my $href = {
c => 3,
a => 1,
b => 2,
};
my %hash = %{$href}; #dereference, {}, the reference into a hash, %
for my $key ( keys %hash ) {
say "$key $hash{$key}";
}
--output:--
c 3
a 1
b 2
回复下一条评论:
(答案发表在 op 下的评论中。)
顺便说一下,perl 非常擅长文本处理,所以如果您无法找出查询的问题,可以使用 perl 处理电子邮件地址:
use strict;
use warnings;
use 5.012;
use Data::Dumper;
use DBI;
use DBD::mysql;
# CONFIG VARIABLES
my $db_type = "mysql";
my $database = "my_db";
my $host = "localhost";
my $port = "3306";
my $user = "root";
my $pword = "";
# DATA SOURCE NAME
my $dsn = "dbi:$db_type:$database:$host:$port";
# PERL DBI CONNECT
my $dbh = DBI->connect($dsn, $user, $pword);
# PREPARE THE QUERY
my $tablename = "mailing";
my $select =<<"END_OF_SELECT";
select addr from $tablename
END_OF_SELECT
my $addr_aref = $dbh->selectcol_arrayref($select); #Returns a reference to a flat array containing all the email addresses
$dbh->disconnect;
my %count_for;
for my $addr (@{$addr_aref}) {
$addr =~ s/.*@//;
$count_for{$addr}++;
}
say Dumper(\%count_for);
--output:--
$VAR1 = {
'google.com' => 2,
'gorilla.com' => 1,
'yahoo.com' => 3
};
我似乎无法找出我的 .pm 文件和脚本的问题。我是 Perl 的新手。
我有一个名为 "project" 的 数据库,还有一个 table 名为 "mailing". 邮件 table 有 7 个条目,我想使用模块显示这些条目。
所以,我有这个自定义模块来登录数据库并进行查询。此模块的名称为 DB.pm
DB.pm 存储在我的 FEDORA 20 上 /root/mysql/GUI/DB.pm.
DB.pm定义如下:
package GUI::DB;
use strict;
use DBI;
use vars qw(@ISA @EXPORT);
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dbConnect query);
#
# dbConnect - connect to the database, get the database handle
#
sub dbConnect {
# Read database settings from config file:
print "Works";
my $dsn = "DBI:mysql:project";
my $dbh = DBI->connect( $dsn,
'root',
'mydatabasepassword',
{ RaiseError => 1 }
);
return $dbh;
}
#
# query - execute a query with parameters
# query($dbh, $sql, @bindValues)
#
sub query {
my $dbh = shift;
my $sql ="SELECT * FROM mailing";
my @bindValues = @_; # 0 or serveral parameters
my @returnData = ();
# issue query
my $sth = $dbh->prepare($sql); //**line number 39 that is giving** error
if ( @bindValues ) {
$sth->execute(@bindValues);
} else {
$sth->execute();
}
if ( $sql =~ m/^select/i ) {
while ( my $row = $sth->fetchrow_hashref ) {
push @returnData, $row;
}
}
# finish the sql statement
$sth->finish();
return @returnData;
}
1;
现在我想在我的脚本中使用这个模块。这是我试过的:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/root/mysql/';
use GUI::DB qw(dbConnect query);
dbConnect();
query();
这是我遇到的错误 -->
无法在 /root/mysql/GUI/DB.pm 第 39 行的未定义值上调用方法 "prepare"。
请帮我解决这个问题。我不确定如何进行。我猜这与参数传递有关。数据库没有问题。它在 CLI 中运行良好。
谢谢:)
_x_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X__X_X_X_X_X__X
直到这里解决了
_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X__X_X_X
进一步的问题是 SQL 命令不起作用。 在我的数据库的邮件 table 中,我有不同域的电子邮件 ID。 例如,一些 ID 是 xyz@gmail.com、12343@gmail.com、bae@yahoo.com 等等,我假设新的电子邮件 ID 将添加到邮件 tables每天都有不同的域名。
我正在尝试编写一个脚本来更新另一个 table,它按域名保存每天的电子邮件地址计数。这是我试过的:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/root/mysql/';
use 5.016;
use Data::Dumper;
use GUI::DB qw(dbConnect query);
my $data = dbConnect();
my @domain = query($data, "SELECT substr(addr,locate('\@',addr)+1) as maildomain, count (*) as mailcount FROM mailing GROUP BY maildomain ORDER BY mailcount DESC");
for my $key (@domain){
say Dumper ($key);
}
但是我收到一个错误,
您的 SQL 语法有误;检查与您的 MariaDB 服务器版本相对应的手册,了解在第 1 行 /root/mysql/GUI/DB.pm 第 44 行 /root/mysql/GUI/DB.pm line 44.
相同的 SQL 语句在 CLI 中没有问题。 任何帮助,将不胜感激。 :)
1) 你的错误是说这里 $dbh 是未定义的:
sub query {
my $dbh = shift;
...
# issue query
my $sth = $dbh->prepare($sql); #<***LOOK HERE***
...这意味着此处必须未定义 $dbh:
sub query {
my $dbh = shift; #<***LOOK HERE***
...
# issue query
my $sth = $dbh->prepare($sql);
2) 让我们看看为什么。您的 dbConnect() 方法 returns $dbh:
sub dbConnect {
# Read database settings from config file:
print "Works";
my $dsn = "DBI:mysql:project";
my $dbh = DBI->connect(
$dsn,
'root',
'mydatabasepassword',
{ RaiseError => 1 }
);
return $dbh; #<***LOOK HERE*****
}
3) 但是,您可以这样调用 dbConnect():
dbConnect();
因为您从未在任何地方保存 return 值,$dbh 被丢弃。
4) 此外,您可以这样调用 query():
query();
然而,您这样定义了 query():
sub query {
my $dbh = shift;
query() sub 认为第一个参数将是数据库句柄——但您没有使用任何参数调用 query()。
您需要这样做:
my $data_base_handle = dbConnect();
my @results = query($data_base_handle);
#do something with @results
回复评论:
I printed @results, this is what I see HASH(0x1d05be8) HASH(0x1d05ba0) HASH(0x1d05b58) HASH(0x1d05b10) HASH(0x1d05ac8) HASH(0x1d05a80) HASH(0x1d05a38)
您写道:
my $row = $sth->fetchrow_hashref;
...这要求 DBI return 每行作为对散列的引用。然后你写道:
push @returnData, $row;
...将每个散列引用推入一个数组。所以 query() return 是一个散列引用数组。符号 HASH(0x1d05be8)
是打印散列引用时 perl 输出的内容。
如果您想查看这些哈希值中的内容,请执行以下操作:
use 5.016; #enable say()
use Data::Dumper;
...
...
for my $href (@results) {
say Dumper($href);
}
要访问哈希引用中的数据,您可以这样做:
use strict;
use warnings;
use 5.016;
use Data::Dumper;
my $href = {
c => 3,
a => 1,
b => 2,
};
my %hash = %{$href}; #dereference, {}, the reference into a hash, %
for my $key ( keys %hash ) {
say "$key $hash{$key}";
}
--output:--
c 3
a 1
b 2
回复下一条评论: (答案发表在 op 下的评论中。)
顺便说一下,perl 非常擅长文本处理,所以如果您无法找出查询的问题,可以使用 perl 处理电子邮件地址:
use strict;
use warnings;
use 5.012;
use Data::Dumper;
use DBI;
use DBD::mysql;
# CONFIG VARIABLES
my $db_type = "mysql";
my $database = "my_db";
my $host = "localhost";
my $port = "3306";
my $user = "root";
my $pword = "";
# DATA SOURCE NAME
my $dsn = "dbi:$db_type:$database:$host:$port";
# PERL DBI CONNECT
my $dbh = DBI->connect($dsn, $user, $pword);
# PREPARE THE QUERY
my $tablename = "mailing";
my $select =<<"END_OF_SELECT";
select addr from $tablename
END_OF_SELECT
my $addr_aref = $dbh->selectcol_arrayref($select); #Returns a reference to a flat array containing all the email addresses
$dbh->disconnect;
my %count_for;
for my $addr (@{$addr_aref}) {
$addr =~ s/.*@//;
$count_for{$addr}++;
}
say Dumper(\%count_for);
--output:--
$VAR1 = {
'google.com' => 2,
'gorilla.com' => 1,
'yahoo.com' => 3
};