On Sat, 31 Aug 2002 11:28:23 +0200 Hallvard B Furuseth <[EMAIL PROTECTED]>
wrote:
> I'm still trying to update through a cursor, and I still can't get it to
> work. The program fails at statement->execute(value) with the message
>
> DBD::Oracle::st execute failed:
> ORA-00936: missing expression (DBD ERROR: OCIStmtExecute)
> at ./test.pl line 27, <STDIN> chunk 1.
>
> What am I doing wrong now?
>
> I wondered if the UPDATE statement should have ":csr" instead of "csr",
> but then the program complained that I could not mix ':' and '?'
> variables.
Even if you can use a placeholder for the cursor name, the DBI statement
handle won't work.
> Here is the program:
>
> #!/local/bin/perl5 -w
>
> my($database, $user, $password) = ("lttest", "hbf");
>
> use strict;
> use DBI;
> use DBD::Oracle qw(:ora_types);
>
> &Login;
> my $dbh = DBI->connect("dbi:Oracle:$database", $user, $password,
> { 'AutoCommit' => 0, 'RaiseError' => 1 });
>
> my $sel = $dbh->prepare("
> BEGIN
> OPEN :csr FOR
> SELECT fakultetnavn FROM lt.fakultet WHERE fakultetnavn IS NOT NULL
> FOR UPDATE;
> END;");
> my $csr;
> $sel->bind_param_inout(":csr", \$csr, 0, { ora_type => ORA_RSET } );
> $sel->execute();
> my $upd = $dbh->prepare("
> UPDATE lt.fakultet SET fakultetnavn=? WHERE CURRENT OF csr");
You have to get the cursor name using the CursorName statement handle
attribute ($csr->{CursorName}). The DBI statement handle is not the
statement name. You will have to test to see if DBD::Oracle supports that
attribute, I don't think it does yet. You might be able to get the cursor
name using Oracle::OCI, but I have not used it so I don't know how.
You might also be able to force the name of the cursor using the alternate
syntax mentioned in the fine manual (perldoc DBD::Oracle):
$sth1 = $dbh->prepare(q{
CREATE OR REPLACE FUNCTION sp_ListEmp RETURN types.cursorType
AS l_cursor types.cursorType;
BEGIN
OPEN l_cursor FOR select ename, empno from emp order by ename;
RETURN l_cursor;
END;
});
$sth2 = $dbh->prepare(q{BEGIN :cursor := sp_ListEmp; END;});
In this case, you _might_ be able to use 'l_cursor' as your cursor name. I
don't currently have Oracle installed, so I can't test this myself.
If the SELECT and the INSERT were part of a PL/SQL package (possibly
temporary), you could open the cursor in a package level variable, return
it from a package function for your fetches, and use it in a package
procedure for the INSERT. For a start see
http://search.cpan.org/src/TIMB/DBD-Oracle-1.12/Oracle.ex/curref.pl .
I've given you a lot of speculation. Please let us know what works if
anything does.
--
Mac :})
** I normally forward private questions to the appropriate mail list. **
Ask Smarter: http://www.tuxedo.org/~esr/faqs/smart-questions.html
Give a hobbit a fish and he eats fish for a day.
Give a hobbit a ring and he eats fish for an age.