I am running into some errors when trying to run a stored procedure through Perl.
The following statements work fine in sqlDeveloper and return expected results
EXEC alpha.beta.do_something()
This does not generate any output, as expected
Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName
This generates output which is given to us from the DBA guys. It has this format in DB terms: Output Type:Ref Cursor. The cursor has two columns, a and b
When running through Perl, I get errors when running the second statement.
This is the Perl code that I am using:
sub execute_procedure {
my $dbh = shift;
my $procedure = shift;
my $statement = "BEGIN $procedure; END;"
my $sth;
eval {$sth = $dbh->prepare($statement);};
eval {$sth->execute();};
if ($@) {
print "failed";
} else {
print "passed";
}
}
# Call 1
execute_procedure($dbh, "alpha.beta.do_something()")
# Call 2
execute_procedure($dbh, "Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName")
Call 1 works as expected, does not generate any errors
Call 2 results in this error
"Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName" results in :PLS-00428: an INTO clause is expected in this SELECT statement (DBD ERROR: error possibly near <> indicator at char 6 in 'BEGIN <>Select alpha.beta.get_result(alpha.STRING_ARRAY('xyz')) from tableName; END;')
if I remove BEGIN and END from the statement in the execute_procedure function like this:
# my $statement = "BEGIN $procedure; END;";
my $statement = "$procedure";
then it does not generate any error, but it returns a result which I don't know how to parse
my $result = $sth->fetchrow_hashref;
print Dumper($result)
results in:
$VAR1 = {
'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless( {}, 'DBI::st' )
};
so, my questions are
What is the right way to execute a stored procedure which uses the SELECT statement? Should it be called with
BEGIN $procedure; END;or without theBEGIN/END?How can I get the actual data from
bless( {}, 'DBI::st' )? I have tried to use different fetch options:fetchrow,fetchrow_hashrefetc. but I am not able to get the actual data from the object
DBImodule will not allow you toprepareandexecutemultiple statements at once. Also, it will depend on the database driver whether$dbh->prepare('BEGIN')succeeds, and the canonical way to create a transaction is to set$dbh->{AutoCommit} = 0before executing the transaction, and then$dbh->commitor$dbh->rollbackaccordingly.AutoCommitis enabled by default, and if you set it to a false value then every database action that you request will be logged, waiting to be actioned or discarded.