【问题标题】:How do I bind DBI parameters at runtime in Perl?如何在 Perl 中在运行时绑定 DBI 参数?
【发布时间】:2012-01-17 21:40:38
【问题描述】:

我有以下代码:

sub run_query { 
    my $name = shift || undef;
    my $sql  = (defined $name ) ? "select * from table where name = ?" :
                                  "select * from table";
    my $sth  = $dbh->prepare("$sql");
    $sth->execute($name);
}

上述子程序需要按如下方式工作:如果提供了$name,则运行第一个查询,否则从表中获取所有数据。如何绑定name 字段?如果提供的话,我希望它动态绑定。

【问题讨论】:

  • 你提供的代码有问题吗?
  • 如果没有提供名称和 $sth->execute($name) 运行。
  • 我的 $name = shift; # ||不需要undef...你不应该引用单独的变量,$dbh->prepare($sql)

标签: perl dbi


【解决方案1】:

来自DBI documentation on cpan

一个常见的问题是让代码片段处理一个可能是 在运行时定义或 undef(非 NULL 或 NULL)。一个简单的 技术是根据需要准备适当的陈述,并且 用占位符代替非 NULL 情况:

  $sql_clause = defined $age ? "age = ?" : "age IS NULL";
  $sth = $dbh->prepare(qq{
    SELECT fullname FROM people WHERE $sql_clause
  });
  $sth->execute(defined $age ? $age : ());

它并不完全适用于您的问题,我假设是如果您添加一个不期望的参数,您的执行将失败。所以,这里的最后一行将适用:

  $sth->execute(defined $name ? $name : ());

【讨论】:

  • 三元运算符也适用于列表上下文,因此您可以说 my ($sql, @args) = defined $name ? ('select ...', $name) : ('select ...');$sth->execute(@args); 将条件逻辑全部放在一个位置。
【解决方案2】:

你可能应该有两个不同的潜艇,但你可以使用

sub run_query { 
    my $sql = @_
       ? "select * from table where name = ?"
       : "select * from table";
    my $sth  = $dbh->prepare($sql);
    $sth->execute(@_);
}

【讨论】:

  • @smith,请注意“未提供”与“未定义”不同。我回答了实际问题(未提供:@_ ? $name : ()),TLP 和 bvr 回答了后者(未定义:defined($name) ? $name : ())。也就是说,在这种特定情况下,这种区别肯定是无关紧要的。
【解决方案3】:

如果没有定义$name,你可以有条件地省略参数:

$sth->execute(defined $name ? $name : ());

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 2011-01-03
    • 2018-10-17
    • 2017-03-26
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 2014-07-14
    • 1970-01-01
    相关资源
    最近更新 更多