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

I'm querying for something using DBD::Oracle.

SELECT this FROM that WHERE foo=$findthis

foo is unique.
I quickly wrote this:

<BR>$sth=$dbh->prepare(q{SELECT this FROM that WHERE <BR>foo=?}); <BR>$sth->execute($findthis); <BR>($returnme) = $sth->fetchrow_array();

but that doesn't handle strings that contain spaces. I've tried a number of different ways of doing it to handle spaces... and all fail. I tried qq{}, taking it out of q{} like:

<BR>$findthis = "find me"; <BR>my $query = "SELECT this FROM that WHERE foo='$findthis'"; <BR>$sth=$dbh->prepare{$query); <BR>... <BR>doesn't work. it prints SELECT this FROM that WHERE foo='find me' + <P> I tried using sqlplus to throw queries directly at the db... and doing + just <CODE> SELECT this FROM that WHERE foo='find me';

worked... so its obviously something about how I'm passing the query... any suggestions?

Replies are listed 'Best First'.
Re: Perl/DBI/Oracle and strings with spaces
by turnstep (Parson) on Dec 09, 2000 at 17:48 UTC
    My first suggestion is to always, always check the status of your DBI calls, like so:
    my $sth=$dbh->prepare($MYSQL) or die "Could not prepare $MYSQL: $DBI:: +errstr\n"; ...etc. for all connects, executes, etc.
    As far as passing spaces, that should not be a problem. When you execute the query, the DBI should quote it for you. Try adding the line
    $dbh->trace(2);
    at the top of your script (after $dbh is created, of course) to see some of the details of what is going on. You could also use the 'quote' function to see exactly what it is sending:
    my $string = "find me"; my $newstring = $dbh->quote($string) or die "Could not quote $string: +$DBI::errstr\n"; print "($string) has become ($newstring)\n";
    ('quote' is mostly used to help escape characters like a single apotrophe, which has special meaning inside SQL.)

    Finally, consider moving your SQL statements into a variable: it will read better, be easier to maintain, and eliminate double typing of the same string in multiple places:

    my $bazfind = shift || "12"; print "Looking for $bazfind.\n"; my $dbh=DBI->connect($SID, $user, $pass, {AutoCommit=>1}) or die "Could not connect to $SID: $DBI::errstr\n"; my $FOOBAR_SQL = "SELECT FOO FROM BARVILLE WHERE BAZ=?"; my $sth=$dbh->prepare($FOOBAR_SQL) or die "Could not prepare $FOOBAR_SQL: $DBI::errstr\n"; $sth->execute($bazfind) or die qq!Could not execute $FOOBAR_SQL with "$bazfind": $DBI::errst +r\n!; ...etc. etc.
    Note how the single declaration of $FOOBAR_SQL not only saves typing it in repeated times, but looks nicer too.
      I would connect using:
      my $dbh=DBI->connect($SID, $user, $pass, {RaiseError=>1});
      and avoid typing all the '.. or die' clauses. Because if you get an error, it gives you a place to start looking and if you need to, you can just add a debug 'print' statement before the failing statement on the next go round.

      That being said, there should be no reason why your statement can not find fields with spaces in them. My guess is that either the prepare is failing or your bind variable has characters besides spaces that you're not expecting. Maybe you need to convert the bind_variable to hex and print that out to see if there are any weird characters like linefeeds sneaking in. One guy I worked with swore up and down that "placeholders don't work" and he avoided using them, and we found that the input was getting a carriage return character. (He also complained that "arrays don't work" for similar reasons, but that's another story - he would always avoid using things instead of debugging and figuring out what's wrong).

      Also, I hope that you don't really have html breaks in the middle of your sql statement because that definitely would cause the prepare to fail.
Re: Perl/DBI/Oracle and strings with spaces
by Fastolfe (Vicar) on Dec 10, 2000 at 09:38 UTC
    turnstep's advice above should always be your first step in diagnosing DBI issues. There is no reason why what you are describing should not work (aside from the spurious HTML tags). If SQL queries with spaces in them did not work, we would all have some serious problems. Likewise with bound values.
    my $looking_for = 'some string with spaces'; my $sth = $dbh->prepare('select field from table where key=?'); $sth->execute($looking_for);
    There is 0 reason why this should not work, especially if you're doing it against DBD::Oracle. I do stuff like this every day without a problem. Try adding some additional error checking and see if that doesn't help you locate your problem.
Re: Perl/DBI/Oracle and strings with spaces
by wardk (Deacon) on Dec 10, 2000 at 08:19 UTC
    Majik about your code...
    <BR>$sth=$dbh->prepare(q{SELECT this FROM that WHERE <BR>foo=?}); <BR>$sth->execute($findthis); <BR>($returnme) = $sth->fetchrow_array(); but that doesn't handle strings that contain spaces. I've tried a nu +mber of di fferent ways of doing it to handle spaces... and all fail. I tried qq{}, taking it out of q{} like:

    I suspect the real reason the above doesn't work (assuming that is exactly the code) is that you have aparent HTML in the SQL. Also, I am curious about the leading <BR>'s in the code snippet.

    select x from y where <BR>this=?

    is certainly going to cause oracle to complain.

    if you can pass the same sql via DBI that you are using in SQL*Plus, you will be successful.

    you are close...good luck

      I suspect he was trying to add those in there to format his code, without knowing/realizing that <code> tags would do that, or maybe the code tags were added by an editor after-the-fact.
Re: Perl/DBI/Oracle and strings with spaces
by boo_radley (Parson) on Dec 10, 2000 at 04:19 UTC
    rather than
    SELECT this FROM that WHERE foo=$findthis
    try
    SELECT this FROM that WHERE foo LIKE $findthis this is especially useful in date fields.
      Don't do this if you don't have a valid reason to do it. If you are wanting/expecting a string to match exactly to what's in the database, you're far better off checking for equality than LIKEness.