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

发布于 2024-08-24 18:27:50 字数 903 浏览 7 评论 0原文

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"});

}
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"});

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心房的律动 2024-08-31 18:27:50

更新:

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

原始答案:

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

此外,没有理由为每个子调用添加 & 前缀:使用 ConnectFailed( ) 而不是 &ConnectFailed( ),除非您了解在子调用前加上 & 的效果并希望达到该效果。

来自 perldoc perlsub

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

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

Update:

Simple, really, you assign the handle returned by the connect call to $l_dbh but invoke a method on $dbh. You must use strict.

Original answer:

The database handle $dbh is not defined which means the connection failed. You should either check return values of your calls, or specify { RaiseError => 1} in the connect call to find out the reason.

Further, there is no reason to prefix every sub invocation with &: Use ConnectFailed( ) instead of &ConnectFailed( ), unless you know the effect of prefixing a sub invocation with & and desire to have that effect.

From perldoc perlsub:

A subroutine may be called using an explicit & prefix. The & is optional in modern Perl, as are parentheses if the subroutine has been predeclared. The & is not optional when just naming the subroutine, such as when it's used as an argument to defined() or undef(). Nor is it optional when you want to do an indirect subroutine call with a subroutine name or reference using the &$subref() or &{$subref}() constructs, although the $subref->() notation solves that problem.

... If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid. (emphasis added).

他不在意 2024-08-31 18:27:50

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

use strict;
use warnings;

...它们会将您从伤害的世界中拯救出来。

早些时候,当您创建数据库句柄时,您应该检查是否发生了不好的事情:

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

如果无法获取数据库句柄,那么继续您的程序就没有任何意义,不是吗?如果你没有死,你至少应该从这个负责处理数据库的函数/方法/代码区域返回。

您的代码还存在其他问题,例如到处使用 eval {} 块以及使用 & 调用函数,但这在本网站的早期问题中已得到相当充分的介绍,因此我鼓励您进行搜索。

You don't show where $dbh is assigned. Presumably you do so earlier. If you do not, then I beseech you to add these two litle lines to all your code files:

use strict;
use warnings;

...and they will save you from a world of hurt.

Earlier on when you create the db handle, you should check if something bad happened:

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

There is no real point in continuing with your program if you cannot get a db handle, is there? If you don't die, you should at least return from this function/method/area of code that is responsible for handling the DB.

There other issues with your code, such as using eval {} blocks everywhere and calling functions with &, but this has been covered quite amply in earlier questions on this site so I would encourage you to do a search.

微凉 2024-08-31 18:27:50

我的($ret)=
$dbh->selectrow_array("从其中选择 1

。 $dbh->quote_identifier($dblink,
'SYSIBM', "SYSDUMMY1") );

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

$dblinks =
$dbh->selectcol_arrayref("选择
db_link 来自 db_links where
票证=\'低\'");

这里看起来很奇怪的另一件事是转义斜杠。我也会重写它。它可能不起作用,但看起来确实不错。

$sql = qq{从 db_links 中选择 db_link
其中票证=低};

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

my ($ret) =
$dbh->selectrow_array("select 1 from
"

. $dbh->quote_identifier($dblink,
'SYSIBM', "SYSDUMMY1") );

Im not an expert at DBI, but this here looks a little wierd to me. Why the single quotes around SYSIBM and double quotes around SYSDUMMY1? This probably wouldn't solve your problem, but it's a good practice. It's not manditory to Use Strict. That's a suggestion.

$dblinks =
$dbh->selectcol_arrayref("select
db_link from db_links where
ticket=\'LOW\'");

This here other thing that looks really odd is the escape Slashes. I would rewrite that too. It might not work, but it sure looks good.

$sql = qq{select db_link from db_links
where ticket=LOW};

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文