Perl DBI Error Msg: Can't call method “selectcol_arrayref” on an undefined value

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

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

回答1:

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).



回答2:

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.



回答3:

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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!