Doctrine DQL execute passing params
I used this DQL in Doctrine
$q->update('produc开发者_Go百科t')
->set('quantity','?')
->where('id=?');
$q->execute(array(20,5));
I check the server for the query and this the generated sql
UPDATE product SET quantity = '20', updated_at = '5'
WHERE (id = '2010-04-26 14:34);
So I need to know why the arguments aren't in the correct places?
I got caught by the exact same bug myself a few days ago. I believe it's caused by a bug in the Timestampable behavior. I'm guessing you have it enabled in the Product model, and Doctrine adds the updated_at field into the series of fields to update (SET) and doesn't pay attention to the fact that you have SQL parameters after that (in the where clause). This bug never comes up when doing SELECTs because Timestampable isn't involved.
The only solution I found is to supply the parameters as you build the query rather than in the execute's array parameter and Doctrine won't get confused. Like this:
$q->update('product')
->set('quantity', 20)
->where('id = ?', 5);
$q->execute();
However if you need to run the same query many times with different values, you'd be losing the performance benefits of separate prepare & execute phases. It appears this is the only solution.
Potentially better solution without performance loss: I have not verified this, however, I would hope that bug would not surface if you used named parameters instead of the anonymous ? placeholders. Doctrine's support for named parameters is described here: http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language
EDIT: I have since tried the alternate approach with named parameters and unfortunately the bug remains. Doctrine gives an error saying you can't mix named and anonymous parameters in the same query. This really should have been fixed a long time ago IMO.
精彩评论