1

Can some one please help me to let me know how to call a oracle subroutine in Perl script

I have a procedure already existing in oracle db. Say below

Case 1) return a ref cursor and accept a IN parameter.

CREATE OR REPLACE PROCEDURE procCursorExample(
  cursorParam OUT SYS_REFCURSOR, userNameParam IN VARCHAR2)
IS
BEGIN
  OPEN cursorParam FOR
    SELECT * FROM DBUSER WHERE USERNAME = userNameParam;
  END;

In SQL developer i can then execute it directly:

DECLARE
  dbUserCursor SYS_REFCURSOR;
  dbUserTable DBUSER%ROWTYPE;
BEGIN
  procCursorExample(dbUserCursor,'mkyong');
  LOOP
    FETCH dbUserCursor INTO dbUserTable;
    EXIT WHEN dbUserCursor%NOTFOUND;
    dbms_output.put_line(dbUserTable.user_id);
  END LOOP;
  CLOSE dbUserCursor;
END;

Can some tell me how to invoke subroutine with argument through Perl script

Anwser

#!/usr/bin/perl
use warnings ;
use strict ;
use DBI;
print "Connecting to DB..";
my $dbh = DBI->connect('dbi:Oracle:xe',  'scott', 'tiger') or
          die "Cannot connect to DB => " . DBI->errstr;

# prepare ????????

am not sure about prepare statement. Any help is highly appreciable.

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
Poorvi
  • 125
  • 8
  • fetchimg the rows from the cursor not happening. $sth->bind_param_inout(":curs", \$cursrecords,0,{ ora_type => ORA_RSET});while($hashRef = $cursrecords->fetchrow_hashref) {print "hashref:$hashRef\n"; foreach(keys %$hashRef) { print "hashref:$hashRef and $_ is $hashRef->{$_}\n"; } } this is not working. – Poorvi Aug 24 '20 at 07:11

1 Answers1

1

Please read the documentation examples for calling stored procedures in Perl with DBD::Oracle, which is the driver you are using.

From this link specifically:

use DBI;
 
my($db, $csr, $ret_val);
 
$db = DBI->connect('dbi:Oracle:database','user','password')
      or die "Unable to connect: $DBI::errstr";
 
# So we don't have to check every DBI call we set RaiseError.
# See the DBI docs now if you're not familiar with RaiseError.
$db->{RaiseError} = 1;
 
# Example 1        Eric Bartley <bartley@cc.purdue.edu>
#
# Calling a PLSQL procedure that takes no parameters. This shows you the
# basic's of what you need to execute a PLSQL procedure. Just wrap your
# procedure call in a BEGIN END; block just like you'd do in SQL*Plus.
#
# p.s. If you've used SQL*Plus's exec command all it does is wrap the
#      command in a BEGIN END; block for you.
 
$csr = $db->prepare(q{
  BEGIN
    PLSQL_EXAMPLE.PROC_NP;
  END;
});
$csr->execute;
 
 
# Example 2        Eric Bartley <bartley@cc.purdue.edu>
#
# Now we call a procedure that has 1 IN parameter. Here we use bind_param
# to bind out parameter to the prepared statement just like you might
# do for an INSERT, UPDATE, DELETE, or SELECT statement.
#
# I could have used positional placeholders (e.g. :1, :2, etc.) or
# ODBC style placeholders (e.g. ?), but I prefer Oracle's named
# placeholders (but few DBI drivers support them so they're not portable).
 
my $err_code = -20001;
 
$csr = $db->prepare(q{
        BEGIN
            PLSQL_EXAMPLE.PROC_IN(:err_code);
        END;
});
 
$csr->bind_param(":err_code", $err_code);
 
# PROC_IN will RAISE_APPLICATION_ERROR which will cause the execute to 'fail'.
# Because we set RaiseError, the DBI will croak (die) so we catch that with eval.
eval {
  $csr->execute;
};
print 'After proc_in: $@=',"'$@', errstr=$DBI::errstr, ret_val=$ret_val\n";
 
 
# Example 3        Eric Bartley <bartley@cc.purdue.edu>
#
# Building on the last example, I've added 1 IN OUT parameter. We still
# use a placeholders in the call to prepare, the difference is that
# we now call bind_param_inout to bind the value to the place holder.
#
# Note that the third parameter to bind_param_inout is the maximum size
# of the variable. You normally make this slightly larger than necessary.
# But note that the Perl variable will have that much memory assigned to
# it even if the actual value returned is shorter.
 
my $test_num = 5;
my $is_odd;
 
$csr = $db->prepare(q{
        BEGIN
            PLSQL_EXAMPLE.PROC_IN_INOUT(:test_num, :is_odd);
        END;
});
 
# The value of $test_num is _copied_ here
$csr->bind_param(":test_num", $test_num);
 
$csr->bind_param_inout(":is_odd", \$is_odd, 1);
 
# The execute will automagically update the value of $is_odd
$csr->execute;
 
print "$test_num is ", ($is_odd) ? "odd - ok" : "even - error!", "\n";
 
 
# Example 4        Eric Bartley <bartley@cc.purdue.edu>
#
# What about the return value of a PLSQL function? Well treat it the same
# as you would a call to a function from SQL*Plus. We add a placeholder
# for the return value and bind it with a call to bind_param_inout so
# we can access its value after execute.
 
my $whoami = "";
 
$csr = $db->prepare(q{
        BEGIN
            :whoami := PLSQL_EXAMPLE.FUNC_NP;
        END;
});
 
$csr->bind_param_inout(":whoami", \$whoami, 20);
$csr->execute;
print "Your database user name is $whoami\n";
 
$db->disconnect;
Francisco Zarabozo
  • 3,676
  • 2
  • 28
  • 54
  • Thanks Francisco. I tried to follow what you have done for proceure with input and output cursor procedure->getenv1( category IN CHAR DEFAULT NULL,cursor1 OUT SYS_REFCURSOR)my $sth= $dbh->prepare(q{ BEGIN getenv1(:category,:curs); END; }); $sth->bind_param(":category", $category1); $sth->bind_param_inout(":curs", \$cursrecords,0,{ ora_type => ORA_RSET}); – Poorvi Aug 24 '20 at 07:03
  • $sth->execute; $sth->finish; print("curserecords=$cursrecords\n"); while($hashRef = $cursrecords->fetchrow_hashref) {print "hashref:$hashRef\n"; foreach(keys %$hashRef) { print "hashref:$hashRef and $_ is $hashRef->{$_}\n"; } } $cursrecords->finish; $dbh->disconnect; cursrecords->fetchrow_hasref()-> is not working . i tried to print the output of cursor,which is not working. can you please help (o/p->curserecords=DBI::st=HASH(0x251faf0)) – Poorvi Aug 24 '20 at 07:08
  • @Poorvi Please don't post code here in the comments, it's extremely hard to read. Update your question with the appropriate explanation of what you did and the code you used, along with what you are seeing or getting from it. Thanks. – Francisco Zarabozo Aug 24 '20 at 16:44
  • .Sorry for that . i couldnt format this . i tried though so i have . i updated here . can you please check this link https://stackoverflow.com/questions/63557071/invoking-a-stored-procedure-with-input-parameter-and-out-cursor-in-perl-script – Poorvi Aug 24 '20 at 19:23