http://www.perlmonks.org?node_id=122716

randomblue has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to write DBI code for Oracle 8.1.7 that uses placeholders. I've tried several variations that I have found on Perlmonks and elsewhere, but none of them work.

Here is what I'm trying to do:

use DBI; use DBD::Oracle; # Define sid, user, password, etc. here my $dbh = DBI->connect($DB_SID, $DB_USER, $DB_PASSWORD, 'Oracle') or die( $dbh->errstr ); my $name = "guppy"; my $sql_statement = 'SELECT foo FROM table_bar WHERE name = ?'; $sth = $dbh->prepare( $sql_statement ) or die( $dbh->errstr ); # This is where I try to replace the placeholder with $name $sth->execute( $name ) or die ( $dbh->errstr ); while( $aref = $sth->fetchrow_arrayref ) { print $aref->[0] ."\n"; } $sth->finish; $dbh->commit; $dbh->disconnect;

When I try to use placeholders, the script runs without any output or errors. The only place where placeholders have worked for me is inside the VALUES() brackets in an INSERT statement. Incidentally, hard-coded SQL statements work just fine. Am I doing something obviously silly? I am new to DBI, so that's quite possible.

Replies are listed 'Best First'.
(Ovid) Re: DBI placeholders
by Ovid (Cardinal) on Nov 02, 2001 at 03:58 UTC

    Here's a slight revision of what you have written. It has several benefits:

    • strict: misspelling variable names can be a bummer.
    • DBI->trace. Read the DBI documentation. This is a great debugging tool.
    • RaiseError is set in the connect string. You no longer need to test every single DBI statement.
    • Took out use DBD::Oracle; DBI will load the correct DBD for you :)
    use strict; use DBI; # Define sid, user, password, etc. here my ( $host, $sid, $user, $passwd ) = some_func(); my $dbh = DBI->connect( "dbi:Oracle:host=$host;sid=$sid", $user, $p +asswd, { RaiseError => 1, AutoCommit => 0 } ) or die DBI->errstr; DBI->trace( 2, 'dbi_trace.txt' ); my $name = "guppy"; my $sql_statement = 'SELECT foo FROM table_bar WHERE name = ?'; my $sth = $dbh->prepare( $sql_statement ); # This is where I try to replace the placeholder with $name $sth->execute( $name ); while( my $aref = $sth->fetchrow_arrayref ) { print $aref->[0] ."\n"; } $sth->finish; $dbh->commit; $dbh->disconnect;

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: DBI placeholders
by runrig (Abbot) on Nov 02, 2001 at 03:53 UTC
    First some comments which may not help your immediate problem, but they might...

    If your connect fails, the error message will not be in $dbh->errstr, because $dbh will be undef. It WILL be in $DBI::errstr, but even easier would be to use RaiseError in the connect, then you could get rid of all the 'or die ...' clauses in the other DBI statement. You are, for instance, not checking for errors in the fetch.

    And you don't need to finish() a statement handle if you're going to fetch all of the rows from it.

    AutoCommit is supposed to be on by default, so you shouldn't need to explicitly commit() anything (and I don't see any inserts/deletes/updates that need committing anyway) unless you turn off AutoCommit.

    And finally, for some actual help, have you tried NOT using placeholders (just quoting 'guppy' directly in the SQL statement), and does it work? If that doesn't work then maybe the problem is that what's in the database is not what you think it is.

    Update: Also, you're using the old-style form of connect (or maybe its just wrong, I forget what the old style was like), which prevents use of attributes like RaiseError during the connect. Look at the docs, and use the correct form ('Oracle' does not belong in that last position, that I'm sure of).

      And finally, for some actual help, have you tried NOT using placeholders (just quoting 'guppy' directly in the SQL statement), and does it work? If that doesn't work then maybe the problem is that what's in the database is not what you think it is.

      That's what strange: if I try to quote 'guppy' directly in the SQL statement, it works (gives me the right output). As soon as I put in the placeholder, and execute it with parameters, it stops working.

Re: DBI placeholders
by randomblue (Beadle) on Nov 02, 2001 at 23:17 UTC
    Well, after trying just about anything under the sun (ie, what I could find in the DBI docs, in Perlmonks and Google), after sifting through DBI->trace output (I, of course, always "use strict" and "-w" to begin with :), I tried to simply drop and re-create the table in the database.

    Guess what, it worked. Apparently, my code wasn't broken, but something was misconfigured in the database. Boggle.

    Anyway, thanks for all your helpful comments. I'll try the RaiseError thing; it looks useful.

Re: DBI placeholders
by andye (Curate) on Nov 03, 2001 at 00:46 UTC
    rb, I realise it's a little late now, but a couple of things that I've found useful:
    • If you 'bind_param' before you 'execute', then you get to find out whether it's the executing or the binding which is failing, and if it's the binding, which binding.
    • Oracle lets you use numbered placedholders - this can be convenient.
    andy.