mysql – 如何在DBI中重用WHERE子句逻辑?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了mysql – 如何在DBI中重用WHERE子句逻辑?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3445字,纯文字阅读大概需要5分钟。
内容图文
免责声明:我第一次使用DBI.
我有一个MySQL表,其中包含许多索引字段(f1,f2,f3等),这些字段用于通过长时间运行的进程生成WHERE子句,这些进程遍历执行各种清理和测试操作的数据库块.
此代码的当前版本的工作方式如下:
sub get_list_of_ids() {
my ($value1, $value2, $value3...) = @_;
my $stmt = 'SELECT * FROM files WHERE 1';
my @args;
if (defined($value1)) {
$stmt .= ' AND f1 = ?';
push(@args, $value1);
}
# Repeat for all the different fields and values
my $select_sth = $dbh->prepare($stmt) or die $dbh->errstr;
$select_sth->execute(@args) or die $select_sth->errstr;
my @result;
while (my $array = $select_sth->fetch) {
push(@result, $$array[0]);
}
return \@result;
}
sub function_A() {
my ($value1, $value2, $value3...) = @_;
my $id_aref = get_list_of_ids($value1, $value2, $value3...);
foreach my $id (@$id_aref) {
# Do something with $id
# And something else with $id
}
}
sub function_B() {
my ($value1, $value2, $value3...) = @_;
my $id_aref = get_list_of_ids($value1, $value2, $value3...);
foreach my $id (@$id_aref) {
# Do something different with $id
# Maybe even delete the row
}
}
无论如何,我要在数据库中转储更多的行,并且我很清楚上面的代码不会扩展.我可以想到几种基于其他语言修复它的方法.在Perl中处理它的最佳方法是什么?
要注意的要点是get_list_of_ids()中的逻辑太长而无法在每个函数中复制;并且所选行的操作变化很大.
提前致谢.
解决方法:
我认为“按比例增加”你的意思是维护术语而不是表现.
对代码的关键更改是将参数作为列/值对传递,而不是使用假定的列集传递值.这将允许您的代码处理您可能添加的任何新列.
DBI-> selectcol_arrayref既方便又快一点,用C语言编写.
如果在连接调用中打开RaiseError,DBI将在错误上抛出异常,而不是一直写或死.你应该这样做.
最后,因为我们从可能不受信任的用户输入编写SQL,所以我注意要转义列名.
其余的在this Etherpad中解释,您可以一步一步地观察您的代码.
sub get_ids {
my %search = @_;
my $sql = 'SELECT id FROM files';
if( keys %search ) {
$sql .= " WHERE ";
$sql .= join " AND ", map { "$_ = ?" }
map { $dbh->quote_identifier($_) }
keys %search;
}
return $dbh->selectcol_arrayref($sql, undef, values %search);
}
my $ids = get_ids( foo => 42, bar => 23 );
如果你希望get_ids返回一个巨大的列表,而不是保留在内存中,那么你可以返回语句句柄并迭代它,而不是拉出整个数组并将其存储在内存中.
sub get_ids {
my %search = @_;
my $sql = 'SELECT id FROM files';
if( keys %search ) {
$sql .= " WHERE ";
$sql .= join " AND ", map { "$_ = ?" }
map { $dbh->quote_identifier($_) }
keys %search;
}
my $sth = $dbh->prepare($sql);
$sth->execute(values %search);
return $sth;
}
my $sth = get_ids( foo => 42, bar => 23 );
while( my $id = $sth->fetch ) {
...
}
您可以通过在数组上下文中返回ID列表或在标量中返回语句句柄来组合这两种方法.
sub get_ids {
my %search = @_;
my $sql = 'SELECT id FROM files';
if( keys %search ) {
$sql .= " WHERE ";
$sql .= join " AND ", map { "$_ = ?" }
map { $dbh->quote_identifier($_) }
keys %search;
}
# Convenient for small lists.
if( wantarray ) {
my $ids = $dbh->selectcol_arrayref($sql, undef, values %search);
return @$ids;
}
# Efficient for large ones.
else {
my $sth = $dbh->prepare($sql);
$sth->execute(values %search);
return $sth;
}
}
my $sth = get_ids( foo => 42, bar => 23 );
while( my $id = $sth->fetch ) {
...
}
my @ids = get_ids( baz => 99 );
最终,您将需要停止手动编码SQL并使用对象关系映射器(ORM),例如DBIx::Class.ORM的一个主要优点是它非常灵活,可以为您完成上述操作. DBIx :: Class可以返回一个简单的结果列表,或者非常强大的迭代器.迭代器是惰性的,在您开始获取行之前它不会执行查询,允许您根据需要更改查询,而不必使您的获取例程复杂化.
my $ids = get_ids( foo => 23, bar => 42 );
$ids->rows(20)->all; # equivalent to adding LIMIT 20
内容总结
以上是互联网集市为您收集整理的mysql – 如何在DBI中重用WHERE子句逻辑?全部内容,希望文章能够帮你解决mysql – 如何在DBI中重用WHERE子句逻辑?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。