I'm working on Windows XP, with Oracle 8.1.7.4.0. The cursors are opened in PL/SQL and returned to DBI via the following wrapper function (which is called by AUTOLOAD):
sub _do_proc {
my $self = shift;
my ($type, $proc, @args) = @_;
unless ($type =~ /^(GET|CREATE|DELETE|ADD|UPDATE)$/) {
die "Unknown type ($type) passed to _do_proc!\n";
}
my $inout = 0;
$inout++ if $type =~ /^(GET|CREATE)$/;
my @params = ();
for (my $i = 0; $i < @args; $i++) {
push @params, ":a$i";
}
push @params, ":out" if $inout;
my $arg_str = join ', ', @params;
my $sql = __unindent(<<" SQLEND");
~BEGIN
~ $PKGNAME.$proc($arg_str);
~END;
SQLEND
my $sth = $self->dbh->prepare($sql);
#print "Prepared statement \n".$sth->{'Statement'}."\n";
my $out;
for (my $i = 0; $i < @args; $i++) {
$sth->bind_param($params[$i], $args[$i]);
}
if ($type eq 'GET') {
$sth->bind_param_inout(':out', \$out, 0, { ora_type => ORA_RSE
+T } );
} elsif ($type eq 'CREATE') {
$sth->bind_param_inout(':out', \$out, 10);
} else {
$out = 1;
}
my $ok = $sth->execute;
if ($ok) {
#print "Successfully executed statement\n";
} else {
return undef;
}
# TODO: Check for statement errors!
return $out;
}
sub AUTOLOAD {
my $self = shift;
die "Not an object\n" unless ref $self;
my $name = our $AUTOLOAD;
$name =~ s/^.*::([^:]+)$/\1/;
return if $name eq 'DESTROY';
if ($name =~ /^(Get|Create|Delete|Add|Update)/ ) {
return $self->_do_proc(uc $1, $name, @_);
} elsif (exists $self->{$name}) {
if (@_) {
return $self->{$name} = shift;
} else {
return $self->{$name};
}
} else {
warn "Attempt to access non-existent method/property: $name\n"
+;
}
}
In the particular instance where the error is occurring, I'm calling the above function, as $db->GetCurveByIdentifier, like this:
my $bb_curve_sth = $db->GetCurveByIdentifier($bb_code);
if ($db->err) {
die "ERROR: ".$db->errstr."\n";
}
my $bb_curve = $bb_curve_sth->fetchrow_hashref;
$bb_curve_sth->finish;
$db->CloseCursor($bb_curve_sth); ## Close the cursor
And there CloseCursor prints the error noted before.
What do you think? |