Musings of ErisDS
beta
ErisDS

When working with large and complex datasets in Symfony, there comes a point where the ORM layer (Propel or Doctrine) causes more problems than it solves. Sometimes it’s necessary to debug large SQL queries built using the ORM layer, and at other times it’s appropriate to bypass the ORM layer entirely.  The following snippets come from projects using Propel, I realise a lot of folks will have moved on to Doctrine but I hope there may be one or two useful things for that here too.

Executing raw SQL in Symfony without Propel Criteria:

For those days when Propel Criteria just isn’t cutting it. Particularly with HAVING and other sub queries that can be quite cumbersome.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$sql = "SELECT %s FROM %s WHERE id = %s";
$sql = sprintf($sql, BranchPeer::NAME, BranchPeer::TABLE_NAME, $branch->getId());

$con = Propel::getConnection(BranchPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$stmt = $con->prepare($sql);
$stmt->execute();

$branches = array();

while($branch = $stmt->fetch(PDO::FETCH_ASSOC))
{
   $branches[] = $branch['name'];
}
return $branches;

If you’re executing a statement which changes data in the database, rather than just retrieving it (i.e. UPDATE) you also need to run commit

1
$stmt->commit();

Debugging PDO Statements

This is a simple trick that I always forget:

1
print_r($stmt->queryString);

Which outputs the raw query:

SELECT branch.name FROM branch WHERE id = 1

Debugging Propel Criteria

Printing or “vardumping” an entire Criteria can be useful to identify problems with complex queries built using propel.

1
2
3
$c = new Criteria();
...
var_dump($c);

This outputs details of all the components of your query, so you can see which part might not be working correctly.

object(Criteria)[87]
  private 'ignoreCase' => boolean false
  private 'singleRecord' => boolean false
  private 'selectModifiers' =>
    array
      empty
  private 'selectColumns' =>
    array
      0 => string 'branch.ID' (length=9)
      1 => string 'branch.ROOT_ID' (length=14)
      2 => string 'branch.NAME' (length=11)
  private 'orderByColumns' =>
    array
      empty
  private 'groupByColumns' =>
    array
      empty
  private 'having' => null
  private 'asColumns' =>
    array
      empty
  private 'joins' =>
    array
      empty
  private 'dbName' => string 'propel' (length=6)
  private 'primaryTableName' => null
  private 'originalDbName' => null
  private 'limit' => int 0
  private 'offset' => int 0
  private 'blobFlag' => null
  private 'aliases' =>
    array
      empty
  private 'useTransaction' => boolean false
  private 'map' =>
    array
      'branch.ID' =>
        object(Criterion)[97]
          private 'value' => int 1
          private 'comparison' => string '=' (length=1)
          private 'table' => string 'branch' (length=6)
          private 'realtable' => string 'branch' (length=6)
          private 'column' => string 'ID' (length=2)
          private 'ignoreStringCase' => boolean false
          private 'db' =>
            object(DBMySQL)[95]
              ...
          private 'clauses' =>
            array
              ...
          private 'conjunctions' =>
            array
              ...
          private 'parent' => null

Perhaps more useful, is printing the result of Criteria’s toString method

1
print_r($c->toString());

Which returns the query and it’s parameters separately:

Criteria: SQL (may not be complete): SELECT branch.ID, branch.ROOT_ID, branch.NAME FROM `branch` WHERE branch.ID=:p1
Params: branch.ID => 1

Please let me know if you have any problems with these snippets, or if you find them useful!

A Note on Snippets: When using frameworks such as Symfony it is often the simplest pieces of code which are the hardest to either find or remember. These snippets are placed here for my own reference and will hopefully be useful to others. If you find them useful or have any suggestions, please let me know.

Related Posts

Share this...

  •  Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Del.icio.us
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Twitter
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to digg
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to FURL
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to reddit
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Technorati
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Newsvine
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Stumble Upon
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to Google Bookmarks
  • Add 'Snippet: Creating & Debugging Complex SQL queries in Symfony ' to FaceBook

Comments

6 Comments to "Snippet: Creating & Debugging Complex SQL queries in Symfony"
  1. 24th Aug

    benbrahim says:

    thanks for your post, i wish to add a like, to produce this sql like this : select branch.ROOT_ID, branch.NAME FROM `branch` WHERE branch.NAME like ‘%all%’ ;
    any idea ?!!!
    this is my code
    $sql = ‘select ‘. self::NAME .” “. self::LASTNAME.” from ” .self::TABLE_NAME .” where “.self::NAME .” like ‘%a%’ ” ;
    but i have error in ‘%a%’ do you now why !!!!
    thanks

  2. 24th Aug

    ErisDS says:

    At first glance, the only problem I can see is that your quotes are all mixed up.

    You need to pay special attention to these, use spacing properly to make it easier to read and you will spot those mistakes more easily:

    1
    $sql = 'SELECT ' .  self::NAME  .  ', '  .  self::LASTNAME . ' FROM ' . self::TABLE_NAME . ' WHERE ' . self::NAME . ' LIKE "%a%"' ;

    Not sure if you’re using doctrine or propel as you didn’t say, but with Propel Criteria there is no reason why you would need to use SQL to create this query. Instead use:

    1
    $criteria->add(self::NAME, "%a%", Criteria::LIKE);
  3. 25th Aug

    benbrahim says:

    i’am using propel but i wish using this type of query $sql = ‘select ‘. self::NAME .” “. self::LASTNAME.” from ” .self::TABLE_NAME .” where “.self::NAME .” like .‘%a%’ ” ;

  4. 26th Aug

    ErisDS says:

    Try copying my code snippet from my earlier comment where I have matched all the quotes properly – yours are all mixed up. Also you are missing the comma between your select fields.

    Try

    1
    print_r($sql);

    as well – that should help show you where the mistakes are.

  5. 26th Aug

    benbrahim says:

    thanks you, i fund the mistak i’m added \” in like condition
    $sql = ‘select ‘. self::NAME .” “. self::LASTNAME.” from ” .self::TABLE_NAME .” where “.self::NAME .” like \”%a%\” ” ;

  6. 26th Aug

    ErisDS says:

    Well that still doesn’t have a comma between your SELECT items, and the quotes are all different – look at the ones around “select” and then look at the other ones… they are not the same.

Add your thoughts

  • XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>