Monday, April 16, 2007

Things I didn't know about PEAR::DB

I have used PEAR::DB for a log time. But I have never read a inside of it.
Today, I got to a problem about placefolder. Let me tell you about it.

I worte a SQL statement like this.

SELECT * FROM hoge WHERE id ! = ?

It looks fine isn't it? But it shows an error like this.

Fatal error: Failed to select from entry[db_error: message="DB Error: mismatch" code=-7 mode=return level=notice prefix="" info="SELECT count(id) FROM entry WHERE feed_id = AND uri = AND id = [DB Error: mismatch]"] in /home/plnet/www/plnet/bin/create_unique_entry.php on line 30

Whats? Why it doesn't replace the string correctly?
I thought the string for replacement is only "?"
But it's wrong!
There are 3 special string for replacement "?", "!" and "&".

So I wrote a sample to know how it works.
Here it is (removed error handling to read friendly :p)

$sql1 = 'INSERT INTO foo (one, two, three) VALUES (?, ?, ?)';
$sql2 = 'INSERT INTO foo (one, two, three) VALUES (?, !, &)';
$data = array(
"John's text",
"'it''s good'",
'./buz.txt' //written "Love letter from Canada."
);

$dbh1 = $db->prepare($sql1);
$res1 = $db->execute($dbh1, $data);

$dbh2 = $db->prepare($sql2);
$res2 = $db->execute($dbh2, $data);


This is a result.

mysql> select * from foo;
+----+-------------+--------------+---------------------------+
| id | one | two | three |
+----+-------------+--------------+---------------------------+
| 1 | John's text | 'it''s good' | ./buz.txt |
| 2 | John's text | it's good | Love letter from Canada. |
+----+-------------+--------------+---------------------------+
2 rows in set (0.00 sec)


? = scalar value (i.e. strings, integers). The system will automatically quote and
escape the data.

! = value is inserted 'as is'

& = requires a file name. The file's contents get inserted into the query (i.e. saving binary data in a db)

Actually they are written in PEAR::DB_common.
I should have read first :p.

And I recalled my excoworker told me that "Be careful when you use prepare and execute. You will have a trouble!".
Now I got it.

I rewrote it like this.
SELECT * FROM hoge WHERE id <> ?
It works well.
(weight 81.6kg BMI 28%)

Labels: ,