Laravel adding parameter with raw queries using Like operators and '%" - mysql

I did some ways to assign parameter but it's not working
Here is my code:
$sqlDefault = "Select * from histories as h where h.status like % :status %";
return DB::select(DB::raw($sqlDefault), ['status' => $status]);
It's not working so I try another ways to assign:
'%:status%' or '%':status'%'
But it's not work
Now I don't use parameter and it's worked perfectlly
$sqlDefault = "Select * from histories as h where h.status like '%$status%'";
The question is how I can use parameter when using like operator with "%" ?

Replace $status with '%'.$status.'%'
$sqlDefault = "Select * from histories as h where h.status like :status ";
return DB::select(DB::raw($sqlDefault,['status' => '%'.$status.'%']));
or just use select only:
return = DB::select(sqlDefault , ['status' => '%'.$status.'%']);

Prepared statement's placeholder doesn't work within '%...%' because it then considered as a string value instead of placeholder. You've to put placeholder directly and then pass the value including "%{$variable}%".
Try this
$sql = "SELECT * FROM `histories` AS h WHERE `h`.`status` LIKE :status";
return DB::select($sql, [ 'status' => "%{$status}%" ]);

If you want to check what queries were run, you may use dd(DB::getQueryLog()).
Try this:
$result = DB::table('histories')->where('status', 'like', '%' . $status . '%')->get();

Try this without assign parameters
DB::table('histories')
->where('status' , 'like', '%'. $status .%' )
->get();
Or you can use direct histories app class like this
Add use App/Histories; on the top
And use query like this
Histories::where('status' , 'like', '%'. $status .%' )->get();

Related

Search multiple words separated by space in laravel 6 doesn't work

I've read several similar posts and I tried them, but still it doesn't work for my site.
When I search a word "think" the search result shows "I think this is it".
However, when I search "I think" the result is "0 match found".
So to achieve multiple words search, I did below:
Controller.php
$keyword = "I think"
$words = explode(' ', $keyword);
$data = Post::where(function ($query) use ($words)
{
foreach($words as $word){
$query->where('example', 'LIKE', '%' . $word . '%');
}
})->get();
However, result is same. "think" shows results. "I think" doesn't hit any results.
also debugged with dd($data)
// $keyword = "think"
"select * from `posts` where (`example` LIKE ?)"
// $keyword = "I think"
"select * from `posts` where (`example` LIKE ? and `example` LIKE ?)"
So what would be wrong? Thank you.
[Additonal info (Edited)]
$bindings = $query->getBindings();
dd($bindings);
// array:2 [▼
0 => "%I%"
1 => "%think%"
]
I would suggest using Laravel scout for this. But alternatively, to do a fuzzy text search in sql.
Or... assuming we don't use MYSQL match features, and we were to use a laravel eloquent.
1) Split the string.
2) use query builder.
$words = explode(' ', $searchString);
$results = Post::where(($q) use ($words) {
$firstWord = array_shift($words);
$q->where('example', $firstCase);
foreach($words as $word) {
$q->orWhere('example', $word);
}
})->get();
SOLVED
It was my bad.
On my blade.php, there was a line
#if (preg_match("/^[0-9a-zA-Z]*$/",$keyword))
this regex didn't have space, that's why it didn't work.
so just changed to:
#if (preg_match("/^[0-9a-zA-Z ]*$/",$keyword))
then totally it worked.
Thank you for helping teachers.
$users = User::where(function ($query) use($userSearch) {
$searchWords = explode(' ', $userSearch);
$query->where('name', 'like', '%'.$searchWords[0].'%');
for($i=1;$i<count($searchWords);$i++) {
$query->where('name', 'like', '%'.$searchWords[$i].'%');
}
})->get();

Query Builder using the like operator and dynamic values

CakePHP Version 3.5.5
What I've got:
I've got search functionality on my index pages which allows a user to search by column and value. The user selects the column from a select list and adds text into an input. I pick up this data with the following which works:
$query = $Users->find()
->where(function ($exp, $q) {
return $exp->like($this->request->getData('column'), $this->request->getData('input') . '%');
})
->andWhere([
'status' => $filter,
'cid_1' => $c1
]);
When using the debugKit it reveals the sql as: (Extract only to help explain)
FROM users Users WHERE (role LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
What I'm trying to do is the following:
$testColumn = $this->request->getData('column');
$testInput = $this->request->getData('input');
$query = $Users->find()
->where(function ($exp, $q) {
return $exp->like($testColumn, $testInput . '%');
})
->andWhere([
'status' => $filter,
'cid_1' => $c1
]);
The $testColumn variable is undefined.
Whe using the debugKit it reveals the sql as: (Extract only to help explain)
FROM users Users WHERE ( LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
IE: The role is not being declared before the LIKE.
What I've tried:
1. return $exp->like("$testColumn", "$testInput" . '%');
Result: Exactly the same - Variable is still undefined.
DebugKit: FROM users Users WHERE ( LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
2. return $exp->like("'$testColumn'", "'$testInput'" . '%');
Result: It added '' before LIKE as can be seen below but I still can't get that variable defined.
DebugKit: FROM users Users WHERE ('' LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
My Question:
Is there a way to use a dynamic value to select the search data.
Update:
Is it that I can't assign getData to a variable in this context.
You can't do this:
$testColumn = $this->request->getData('column');
return $exp->like($testColumn, $testInput . '%');
But you can do this:
$testColumn = $this->request->getData('column');
echo 'testColumn is ' . $testColumn . '<br />';
if ($testColumn === 'role') {
echo 'in column passed ' . '<br />';
}
else {
echo 'in column failed ' . '<br />';
}
Thanks. Z.
////////////////////////////////////////////////////////////////////////////////
Alimon Karim as requested.
I'm using post and my url is: https://localhost/app/users/search
Thanks Alimon, it works.
Replace
->where(function ($exp, $q) {
with
->where(function ($exp, $q) use ($testColumn,$testInput) {

Laravel 4.x, Eloquent multiple conditions

I've tried to this:
Product::where(['product_id' => $product->id, 'catalog_id' => $key])->first();
This isn't working at all. When I'm doing this:
Product:where('product_id', $product->id)->where('catalog_id', $key)->first();
It just works fine. I've searched in the documentation of Laravel,
and found nothing.
Is there any option to using the where function with an array in it ?
You need to use where() individually. If you want to dynamically building the query you can do something like:
$wheres = array('product_id' => $product->id, 'catalog_id' => $key);
$q = new Product;
foreach ( $wheres as $k => $v ) {
$q = $q->where($k, $v);
}
$products = $q->first();
In fact we were all wrong ;)
As of latest version of the framework you can do exactly what you wanted.
Check this commit and update Laravel if you need that feature.
https://github.com/laravel/framework/commit/87b267a232983abdac7c23c2dc6b1b270dd24b8a
Product::whereNested(function($query) use ($key, $product){
$query->where('product_id', $product->id);
$query->where('catalog_id', $key);
})->get();
Laravel's wheres use an and condition by default:
$products = Product::where('this','=','that')->where('something','=','hello')->get();
is somewhat equivalent to:
SELECT * FROM products WHERE this = 'that' AND something = 'hello';
You simply chain the ->where() methods together. No need for an array.
If you want to use an or condition:
$products = Product::where('this','=','that')->orWhere('something','=','hello')->get();

Codeigniter LIKE with wildcard(%)

I have simple database query in codeigniter, however I cannot get search to work with wildcard. This is my code:
$this->db->like('film.title',"%$query%");
$this->db->escape_like_str($query);
$res = $this->db->get('film');
If I remove wildcard(%) then search works fine. Also $query is just string with user input. Any help is appreciated.
$this->db->like() automatically adds the %s and escapes the string. So all you need is
$this->db->like('title', $query);
$res = $this->db->get('film');
See the CI documentation for reference: CI 2, CI 3, CI 4
$this->db->like('title', 'match', 'before');
// Produces: WHERE title LIKE '%match'
$this->db->like('title', 'match', 'after');
// Produces: WHERE title LIKE 'match%'
$this->db->like('title', 'match', 'both');
// Produces: WHERE title LIKE '%match%'
For Full like you can user :
$this->db->like('title',$query);
For %$query you can use
$this->db->like('title', $query, 'before');
and for $query% you can use
$this->db->like('title', $query, 'after');
$this->db->like()
This method enables you to generate LIKE clauses, useful for doing searches.
$this->db->like('title', 'match');
Produces: WHERE title LIKE '%match%'
If you want to control where the wildcard (%) is placed, you can use an optional third argument. Your options are ‘before’, ‘after’, ‘none’ and ‘both’ (which is the default).
$this->db->like('title', 'match', 'before');
Produces: WHERE title LIKE '%match'
$this->db->like('title', 'match', 'after');
Produces: WHERE title LIKE 'match%'
$this->db->like('title', 'match', 'none');
Produces: WHERE title LIKE 'match'
$this->db->like('title', 'match', 'both');
Produces: WHERE title LIKE '%match%'
If you do not want to use the wildcard (%) you can pass to the optional third argument the option 'none'.
$this->db->like('title', 'match', 'none');
// Produces: WHERE title LIKE 'match'
I'm using
$this->db->query("SELECT * FROM film WHERE film.title LIKE '%$query%'"); for such purposes
Searching multiple fields at once can be done like so...
function search($search)
{
$sql = "SELECT * FROM some_table
WHERE UPPER(a_name) LIKE ?
OR
UPPER(a_full_name) LIKE ?
OR
UPPER(a_city) LIKE ?
OR
UPPER(a_code) LIKE ?
";
$arr = array_map(array($this,"wrapLIKE"),array($search, $search, $search, $search));
$r = $this->db->query($sql, $arr);
return $r;
}
function wrapLIKE($string)
{
return strtoupper("%$string%");
}

"No result was found for query although at least one row was expected." Query should display records though in Symfony

I'm trying to retrieve content using two items in the URL. Here is the php/symfony code that should do it:
$em = $this->getDoctrine()->getEntityManager();
$repository = $this->getDoctrine()
->getRepository('ShoutMainBundle:Content');
$query = $repository->createQueryBuilder('p')
->where('p.slug > :slug')
->andWhere('p.subtocontentid > :parent')
->setParameters(array(
'slug' => $slug,
'parent' => $page
))
->getQuery();
$content = $query->getSingleResult();
However, when this code is executed it returns the following error:
No result was found for query although at least one row was expected.
I have done some tests, and the data held in the $slug and $page variables hold the correct information. I have also tested the MySQL query and the query brings up the desired result, which confuses me further.
Have I missed something?
As it was answered here
You are getting this error because you are using the
getSingleResult() method. it generates an Exception if it can't find
even a single result. you can use the getOneOrNullResult() instead
to get a NULL if there isn't any result from the query.
Query#getSingleResult(): Retrieves a single object. If the result
contains more than one object, an NonUniqueResultException is thrown.
If the result contains no objects, an NoResultException is thrown. The
pure/mixed distinction does not apply.
No result was found for query although at least one row was expected.
Another reason could be:
You did this
$query = $this->getEntityManager()
->createQuery('
SELECT u FROM MyBundle:User u
WHERE u.email = :email')
->setParameter('email', $email);
return $query->getSingleResult();
Instead of this
$query = $this->getEntityManager()
->createQuery('
SELECT u FROM MyBundle:User u
WHERE u.email = :email')
->setParameter('email', $email);
$query->setMaxResults(1);
return $query->getResult();
Don't you want to use "=" instead of ">" ?
If you've got this message because used
$content = $query->getSingleResult();
you can just replace it with the row below
$content = $query->getOneOrNullResult(AbstractQuery::HYDRATE_SINGLE_SCALAR) ?? 0;