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.
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.
Another variant using CDbCriteria
CDbCriteria::addSearchCondition
thanks!
Thanks, it save my day :D
Thanks for this guidance
I have a question how can I perform a search with a string match like this Manhattan, NY
Thanks
Warning
Since v5.11.6 MySQL includes indexes and especially FULLTEXT search
php pdo prepare repetitive variables
Using $ this-> params in the query must be unique for each condition, as shown below:
http://stackoverflow.com/a/7604080
Tnx :) CONCAT is another way
Another way to have the LIKE expressions (especially RLIKE(REGEXP)) within the long Queries is to CONCAT
$db-> createCommand("SELECT ... WHERE ... LIKE CONCAT('%', :param1, '%', :param2) ESCAPE '='") ->query(array( ':param1' => YourTools::EscapeLikeWildCards($thisModel->attribute1, '='), ':param2' => YourTools::EscapeLikeWildCards($thisModel->attribute2, '='), ))
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.