Creating a parameterized LIKE query

You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#4) »

  1. Alternate versions:
  2. Better: use CDbCriteria::compare()

It's common to see users wishing to make substring DB queries, using the % metacharacter used to match anything; in this FAQ we'll search the tbl_comments table from the blog tutorial hoping to find the text in $match in the content column

A frequently seen yet incorrect effort:

$q = new CDbCriteria( array(
    'condition' => "content LIKE '%:match%'",      // DON'T do it this way!
    'params'    => array(':match' => $match)
) );

$comments = Comments::model()->findAll( $q );     // finds nothing

fails to find anything. And the version without single quotes around the :match yields an SQL error.

This search is properly achieved by moving the % metacharacters into the bound parameter:

$q = new CDbCriteria( array(
    'condition' => "content LIKE :match",         // no quotes around :match
    'params'    => array(':match' => "%$match%")  // Aha! Wildcards go here
) );

$comments = Comments::model()->findAll( $q );     // works!

The :match in the condition should not have quotes - Yii handles this parameter binding properly (adding the quotes will make it find nothing).

Alternate versions:

// directly into findAll()
$comments = Comments::model()->findAll(
    'content LIKE :match',
    array(':match' => "%$match%")
);

// merging in a parameterized scope:
$this->getDbCriteria()->mergeWith( array(
    'condition' => 'content LIKE :match',
    'params'    => array(':match' => "%$match%")
) );

Better: use CDbCriteria::compare()

If the query uses a direct CDbCriteria object, it's more efficient (and just as safe) to do a simple substring match with the compare() method, which handles it all directly.

$q = new CDbCriteria();
$q->compare('content', $match, true);    // true=partial match

$comments = Comments::model()->findAll( $q );

The third parameter of true asks for a partial match, which Yii turns into a LIKE query using % wildcards before and after the match variable.

13 0
21 followers
Viewed: 144 662 times
Version: Unknown (update)
Category: FAQs
Written by: Steve Friedl
Last updated by: Asgaroth
Created on: May 29, 2011
Last updated: 13 years ago
Update Article

Revisions

View all history

Related Articles