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


in reply to DBH Insert of Binary Data

For this sort of thing you'll want to bind the values.

my $sth = $dbh->prepare("INSERT INTO `table` (`blobcolumn`) VALUES ( ? )"); $sth->execute($bindata) or die $dbh->errstr;

The "?" gets replaced by your $bindata when the query executes, and DBI takes care of everything for you. (This feature also allows you to prepare a statement handle once and execute it several times with changing values.)

Replies are listed 'Best First'.
Re^2: DBH Insert of Binary Data
by cowboy (Friar) on Mar 19, 2005 at 03:13 UTC
    Placeholders, are the way to go in mysql. In postgres (DBD::pg) you explicitly need to do something like:
    my $sth = $dbh->prepare("INSERT INTO foo (blob) VALUES (?)"); $sth->bind_param(1, $blob_data, { pg_type => DBD::Pg::PG_BYTEA });
    This is a pain in the ass, I wish postgres would just let placeholders work with binary magically like mysql does.
Re^2: DBH Insert of Binary Data
by Hero Zzyzzx (Curate) on Mar 18, 2005 at 20:40 UTC

    My understanding was that explicitly using $dbh->quote was pretty much the same as using placeholders, in terms of escaping characters that would break SQL.

    Put another way, shouldn't the two statements above be pretty much equivalent, except that yours is reusable?

    -Any sufficiently advanced technology is
    indistinguishable from doubletalk.

    My Biz

      NO! In most DBDs, the quote method escapes things that need to be escaped and the result is put into a SQL string. The parser needs to then parse that string. A placeholder is different because a) there is no escaping of the value (binary values may not like being escaped) and b) the value is *never* put back into the SQL string, it is sent separately to the RDBMS which means that there is no opportunity for SQL injection since the placeholder values is clearly known to be a value, not part of a SQL string and it also means that the parser has no work - it never sees the placeholder value. Think of it like this:
         1)  SELECT x FROM FROM y WHERE $myquoted_value =z
         2a) SELECT x FROM y WHERE ? = 1
         2b) $value_to_insert
      
      With #1, the RDBMS sees everything at once and has to separate out $myquoted_value, possibly being tricked about what to spearate if $myquoted_value contains SQL injection. With #2, the SQL statement and the value are passed sparately and the RDBMS does not need to separate them again. Placeholders are better for security and often better for performance.
        I mostly agree, but AFAIK, the $dbh->quote() method is (or should be) implemented by the specific DBD driver and should always escape correctly. Now, there might be situations or database where you can't just insert a quoted string in a BLOB, but SQL injection should not be possible with a $dbh->quote()d string.

        The top post should remove the quotes around the quoted string, though, as $dbh->quote already provides them. Never mind, there aren't any.