【问题标题】:Perl cgi bind dynamic number of columnsPerl cgi 绑定动态列数
【发布时间】:2016-02-04 11:43:10
【问题描述】:

我正在尝试从数据库中进行简单的选择,问题是我希望相同的脚本能够选择其中的任何表。在需要将列绑定到变量之前,我已经解决了所有问题,因为它们必须动态生成,我只是不知道该怎么做。

代码如下:

 if($op eq "SELECT"){
    if ($whr){
    $query1 = "SELECT $colsf FROM $tab WHERE $whr";
    }else{
    $query1 = "SELECT $colsf FROM $tab";
    }
    $seth = $dbh->prepare($query1);
    $seth->execute();
    foreach $cajas(@columnas){
    $seth->bind_col(*$dynamically_generated_var*);
    }
    print $q->br();
    print $q->br();
    print $q->br();

变量@columans 包含所选列的名称(变化很大),我需要为$seth->bind_col() 上的每个列分配一个变量。

我怎样才能做到这一点?

【问题讨论】:

  • bind_col() 在这里使事情复杂化,并没有真正为您带来任何好处; fetchrow_*() 方法更适合此类问题。顺便说一句,要小心那个 SQL,否则用户可以用那个查询做各种讨厌的事情。您必须从外部清理您放入 $colsf 的每一位数据。

标签: perl cgi dbi


【解决方案1】:

在这里使用bind_col 不会为您带来任何好处。正如您已经知道的那样,它用于将固定数量的结果绑定到一组变量。但是你没有固定的集合

考虑哦,我可以动态地创建它们是一个很常见的错误。它会给你into all kinds of trouble later。 Perl 有一个专门针对这个用例的数据结构:散列

DBI 内置了一堆函数,用于在execute 之后检索数据。其中之一是fetchrow_hashref。它将结果作为哈希引用返回,每列一个键,一次一行。

while (my $res = $sth->fetchrow_hashref) {
  p $res; # p is from Data::Printer
}

假设结果如下所示:

$res = {
  id => 1,
  color => 'red',
}

您可以通过说$res->{color} 来访问颜色。 perlrefperlreftut 上的 perldocs 有很多关于此的信息。

请注意,命名语句句柄变量的最佳做法是$sth

在您的情况下,您有动态数量的列。这些必须以col1, col2, col3 的格式加入。我猜你已经在$colsf 中做到了。 $tab 中的表格非常明显,所以我们只剩下 $whr 了。

这部分很棘手。这对always sanitize your input 很重要,尤其是在 CGI 环境中。对于 DBI,最好使用 placeholders 来完成。他们会为您处理所有的转义,并且易于使用。

my $sth = $dbi->prepare('select cars from garage where color=?');
$sth->execute($color);

现在我们不需要关心颜色是redblue 还是' and 1; --,它们可能有损坏的东西。如果这一切都非常动态,请改用$dbi->quote

让我们把它放在你的代码中。

use strict;
use warnings;
use DBI;

# ...

# the columns
my $colsf = join ',', @some_list_of_column_names; # also check those!

# the table name
my $table = $q->param('table');
die 'invalid table name' if $table =~ /[^a-zA-Z0-9_]/; # input checking

# where
# I'm skipping this part as I don't know where it is comming from

if ($op eq 'SELECT') {
  my $sql = 'SELECT $colsf FROM $table';
  $sql .= ' WHERE $whr' if $whr;

  my $sth = $dbh->prepare($sql) or die $dbi->errstr;
  $sth->execute;

  my @headings = $sth->{NAME}; # see https://metacpan.org/pod/DBI#NAME1
  while (my $res = $sth->fetchrow_hashref) {
    # do stuff here
  }
}

【讨论】:

    猜你喜欢
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多