tags:

views:

1856

answers:

3

What is the preferred way to insert strings that can contain both single and double quotes (",') into MySql using DBI? For example, $val1 and $val2 can contain quotes:

my $dbh = DBI->connect( ... );
my $sql = "insert into tbl_name(col_one,col_two) values($val1, $val2)";
my $sth = $dbh->prepare($sql);
$sth->execute();
+17  A: 

Use a bound query using

$sth = $dbh->prepare("insert into tbl_name(col_one,col_two) values(?,?)");
$sth->execute($val1, $val2);

If you use bound variables, everything is escaped for you.

Update: Changed my example to correspond with the example edited into the question.

Update: I don't know why Adam deleted his answer, but if for some reason you can't use bound variables (aka "placeholders"), you can also use $dbh->quote($var) on the variable. For example:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
    $dbh->quote(q("Don't"));
Paul Tomblin
It is generally referred to as using placeholders.
Mr. Muskrat
Placeholders also have the very useful property of protecting against SQL injection attacks. Use them. Always. *Never* place user-supplied data into your queries directly.
Dave Sherohman
'executeUpdate' should just be 'execute' (and it's an insert anyway, not an update :-) BTW Adam, quote() is also a good answer, there are times when it is preferable to placeholders. But yes, never use user-supplied data directly in your queries, or suffer the wrath of Bobby Tables.
runrig
Well, the community has spoken on this one. :)
Adam Bellaire
@Adam you shouldn't have deleted your answer. It had some usual information.
Paul Tomblin
+1  A: 

Use the quote() method. It will intelligently handle the quoting for you. Example from the docs:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
            $dbh->quote("Don't");

Slightly modified to have both types of quotes:

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
            $dbh->quote(q("Don't"));
Adam Bellaire
I don't remember why I deleted this answer either. So I'm undeleting it. :)
Adam Bellaire
+2  A: 

One small caveat on the bound placeholders, I build a rather large database-loading script that initially used bound placeholders in an older version of Perl/DBI and found what appears to be a memory leak in the placeholder implementation, so if you're looking at using them in a persistent process/daemon or in a high-volume context you may want to make sure process size doesn't become an issue. Switching over to building the query strings using the quote() method eliminated the issue for me.

Aquatoad
interesting, although it might just have been the fact that statement handle objects were created explicitly that caused memory management issues in Perl - i.e. memory fragmentation. Perl really isn't very good at reclaiming freed memory...
mjy