Perl DBI错误消息:无法在未定义的值上调用方法“selectcol_arrayref”

时间:2010-03-05 16:00:53

标签: perl oracle dbi

my $dblinks = '';
$dblinks = $dbh->selectcol_arrayref("select db_link from db_links where ticket=\'LOW\'");
my $success = 0;
for my $dblink (@$dblinks) {
  $success = eval {
    my ($ret) = $dbh->selectrow_array("select 1 from "
      . $dbh->quote_identifier($dblink, 'SYSIBM', "SYSDUMMY1") );
    $ret;
  };

  if ($success) {
    &Logging (3, $I, "connect_${G_CONNECT_COUNT}", "Connect success for $dblink");
  } else {
    # Read thru the selectcol_array, check for an oracle error
    $l_msg="$dblink Result doesn't match 1";
    @l_errstr=();
    &ConnectFailed ($p_host, $p_db, $p_ars, $p_ars_sev, $l_msg, $p_cid, @l_errstr);
    # Raise a Ticket with Oracle message
    &Logging (3, $I, "connect_${G_CONNECT_COUNT}", "Connect failed for $dblink");

  }
    $l_dbh->commit();
    $l_dbh->do(qq{alter session close database link  "$dblink"});

}

3 个答案:

答案 0 :(得分:5)

更新

简单,实际上,您将connect调用返回的句柄分配给$l_dbh,但在$dbh上调用方法。您必须使用strict

原始答案:

未定义数据库句柄$dbh,这意味着连接失败。您应该检查来电的返回值,或在{ RaiseError => 1}来电中指定connect以找出原因。

此外,没有理由为每个子调用添加前缀&:使用ConnectFailed( )而不是&ConnectFailed( ),除非您知道使用{{1}为子调用添加前缀的效果并渴望产生这种效果。

来自perldoc perlsub

  

可以使用显式&前缀调用子例程。 &在现代Perl中是可选的,如果子例程已经预先声明,则是括号。仅在命名子例程时&不是可选的,例如当它用作&defined()的参数时。当您想使用undef()&$subref()构造对子例程名称或引用进行间接子例程调用时,它也不是可选的,尽管&{$subref}()表示法可以解决该问题。

     

...如果使用$subref->()形式调用子例程,则参数列表是可选的,如果省略,则不为子例程设置&数组:@_调用时的数组对子程序是可见的。 这是新用户可能希望避免的效率机制。(强调补充)。

答案 1 :(得分:4)

您不会显示分配$dbh的位置。想必你早点这样做。如果你不这样做,那么我恳请你将这两条文字添加到你的所有代码文件中:

use strict;
use warnings;

......他们会把你从一个受伤的世界中拯救出来。

在您创建数据库句柄之前,您应该检查是否发生了错误:

my $dbh = DBI->connect($data_source, $username, $password)
        or die $DBI::errstr;

如果您无法获得数据库处理,继续使用您的程序是没有意义的,是吗?如果你没有死,你至少应该从负责处理数据库的代码的函数/方法/区域返回。

您的代码存在其他问题,例如在任何地方使用eval {}块并使用&调用函数,但在本网站的早期问题中已经详细介绍了这一点,所以我鼓励您这样做搜索。

答案 2 :(得分:0)

  

我的($ ret)=   $ dbh-> selectrow_array(“从中选择1   “         。 $ dbh-> quote_identifier($ DBLINK,   'SYSIBM'“SYSDUMMY1”));

我不是DBI的专家,但这对我来说看起来有点奇怪。为什么SYSIBM周围的单引号和SYSDUMMY1周围的双引号?这可能无法解决您的问题,但这是一个很好的做法。这不是使用Strict的要求。这是一个建议。

  

$ dblinks =   $ dbh-&GT; selectcol_arrayref(“选择   来自db_links的db_link   票= <强> \ 'LOW \'“);

这里其他看起来很奇怪的东西就是逃避斜线。我也会改写它。它可能不起作用,但它看起来确实很好。

  

$ sql = qq { db_links中选择db_link   其中ticket = LOW};

     

$ dblinks =   $ dbh-&gt; selectcol_arrayref($ sql,undef);