Hi i need to build a Query with 3 likes in Yii2. it´s a formsearch.
Select vchName, vchType, vchEmail from Tours where vchName like _Post('vchname') and vchType like _Post('vchType') and vchEmail like _Post('vchEmail')
i try this, but it's wrong. pls help.
$query->where(['like','vchName',Yii::$app->request->post('vchName')])->
andWhere(['like','vchJourney',Yii::$app->request->post('vchJourney')])->
andWhere(['like','vchTypesOfTours',Yii::$app->request->post('vchTypesOfTours')]);
this is the error:
.Invalid Argument – yii\base\InvalidArgumentException
Operator 'LIKE' requires two operands.
As your error message hints, Operator 'LIKE' requires two operands.
I'm assuming that you have situations where your code is running on a non-POST request or you're simply not supplying all the POST params that you need to run the query.
I sugest using method andFilterWhere instead of andWhere.
$query
->andFilterWhere(['like','vchName',Yii::$app->request->post('vchName')])
->andFilterWhere(['like','vchJourney',Yii::$app->request->post('vchJourney')])
->andFilterWhere(['like','vchTypesOfTours',Yii::$app->request->post('vchTypesOfTours')]);
Note that if any of the params supplied are empty (like Yii::$app->request->post('vchName')), the condition itself wil be skipped.
Verify that you are using/posting those variables correclty. espacially since the default notation should be something like Yii::$app->request->post('SearchFormName')['vchName']
Related
I am trying to use a LIKE comparison in a doctrine DQL in a MySQL database.
It works directly in SQL in the database and looks like this:
SELECT *, (name LIKE '%testO%') as partOfName
from organization
ORDER BY partOfName DESC;
This works just fine.
Now I try to implement this logic in Doctrine. My Querybuilder looks like this:
oQueryBuilder
->from(OrganizationEntity::class, organization)
->select('organization')
->addSelect('(organization.name LIKE %:searchTerm%) AS searchTermIsPartOfName')
->setParameter('searchTerm', $sSearchTerm)
->orderBy('searchTermIsPartOfName', 'DESC')
;
Trying to run it or get the SQL out of it gives me the following error:
[Syntax Error] line 0, col 97: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got 'LIKE'
It is definitely the part about the LIKE. I commented the last three lines out and it works.
How do I translate the above working SQL into Doctrine DQL?
LIKE expressions are covered under Conditional Expressions in DQL's grammar. And unfortunately, it's not possible to use these directly within a SelectExpression.
However you can use them within a CaseExpression, which can be used in a SelectExpression, and replicate the same behaviour:
->addSelect('CASE WHEN (organization.name LIKE :searchTerm) THEN 1 ELSE 0 END AS searchTermIsPartOfName')
->setParameter('searchTerm', "%{$sSearchTerm}%")
(there was also a minor issue about your LIKE expression - I'm pretty sure the % signs need to be part of the parameter value, not the query itself)
you forgot '' after LIKE, replace with string
->addSelect('(organization.name LIKE %:searchTerm%) AS searchTermIsPartOfName')
on
->addSelect('(organization.name LIKE \'%:searchTerm%\') AS searchTermIsPartOfName')
For a search query I have the following:
DB::whereRaw('column = ?', 'foo')->orWhereRaw('column IS NULL')->get();
Adding the orWhereRaw statement gives me less results than only the whereRaw. Somehow it seems to ignore the first when adding the other. It is included in the SQL statement. Is there another way to compare for a string and null value?
I have also tried the following, as suggested below:
return self::select('id')
->where('current_state', 'unavailable')
->orWhereNull('current_state')
->get();
If I change the order (the whereNull first and the where second) this also gives me different results. It appears as if the inclusive query doesn't function correctly in correspondence with the where clause. If I use to regular where clauses I don't experience any issues.
Running SELECT * FROM events WHERE current_state='unavailable' OR current_state IS NULL; does produce the correct result for me.
Don't use whereRaw to check for null. You can use this instead:
->orWhereNull('column')
The proper way to do the first where, unless you're doing something extra such as a mysql function, is just to pass the column along like this:
where('column', '=', 'foo')
You can actually eliminate the equals, since it defaults to that. So your query would be:
DB::table('table')->where('column', 'foo')->orWhereNull('column')->get();
For detecting the existence of a key in a hstore, I need to run a query like this:
SELECT * FROM tbl WHERE hst ? 'foo'
However, that gives me a PDOException:
PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'
Is there any way to escape the question mark so PDO won't pick it up as a placeholder? I've tried with up to four backslashes, as well as a double question mark (??), but nothing seems to persuade PDO to leave the question mark alone.
Use the function call form. According to the system catalogs, the hstore ? operator uses the exist function:
regress=# select oprname, oprcode from pg_operator where oprname = '?';
oprname | oprcode
---------+---------
? | exist
(1 row)
so you can write:
SELECT * FROM tbl WHERE exist(hst,'foo');
(Personally I'm not a big fan of hstore's operator-centric design and documentation, I think it discards the useful self-documenting properties of a function based interface without any real benefit and I usually use its function calls rather than its operators. Just because you can define operators doesn't mean you should.)
I had the same problem when searching on JSONB data. The full question is here
SELECT * FROM post WHERE locations ? :location;
The workaround on PostgreSQL 9.5 is similar:
SELECT * FROM post WHERE jsonb_exists(locations, :location);
I also opened a ticket at PHP bug tracing system
Update
As Diabl0 mentioned, the proposed solution work but does not use the index.
Tested with:
CREATE INDEX tempidxgin ON post USING GIN (locations);
I suggest you disable PDO native prepared statement so question marks will be ignored:
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
Note:
This question can be considered as duplicate of this Question.
It does point to the same problem with PDO. But its workaround solution is a bit different as the target differ. I will post there the workaround for JSONB and the link to the PHP ticket.
When I prepare the following query:
SELECT * FROM post WHERE locations ? :location;
The following warning occur:
Warning: PDO::prepare(): SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters in /path/file.php on line xx
The question mark is an valid PostgreSQL operator but PDO condsider it as a placeholder.
Is there a proper way to configure PDO to ignore question mark as placeholders?
I will post a workaround bellow. Hoping there is a better way
Edit
I add a ticket at PHP bug tracing system
This is a workaround to my problem. It solve the problem by using PostgreSQL function to replace the ? operator.
I don't really like it because it does not make PDO more compliance to PostgreSQL. But I found no real solution.
CREATE FUNCTION json_key_exists(JSONB,TEXT) RETURNS BOOLEAN LANGUAGE SQL STABLE AS $f$
SELECT $1 ? $2
$f$;
And now I can use the query:
SELECT * FROM post WHERE json_key_exists(locations, :location);
The workaround was suggested by the fabulous RhodiumToad from freenode #postgresql
Edit
As #Abelisto suggested, there is no need to create the function above as jsonb_exists(jsonb, text) is avialabe
Since PHP 7.4, supports for escaping question mark have landed.
(...) question marks can be escaped by doubling them (...). That means that the “??” string would be translated to “?” when sending the query to the database, whereas “?” is still going to be interpreted as a positional parameter placeholder.
In your example, you can use:
$sql = "SELECT * FROM post WHERE locations ?? :location;";
Ok, the simplest way is to create the new operator with the same options, like:
-- Operator: ~!##%^&(jsonb, text)
-- DROP OPERATOR ~!##%^&(jsonb, text);
CREATE OPERATOR
~!##%^& -- Change it to any other non-conflicted symbols combination
(
PROCEDURE = jsonb_exists,
LEFTARG = jsonb,
RIGHTARG = text,
RESTRICT = contsel,
JOIN = contjoinsel);
COMMENT ON OPERATOR ~!##%^&(jsonb, text) IS 'key exists';
(Original script was generated by pgAdmin)
And use it in usual way like
SELECT * FROM post WHERE locations ~!##%^& :location;
You can use
jsonb_exists instead of ?
jsonb_exists_any instead of ?|
jsonb_exists_all instead of ?&
But there is no documentions on postgresql site.
For searching keys and according to Yoann answer, I have tested that the expression ( jsonbData ? 'keySearched' ) is equivalent to jsonb_exists(jsonbData , 'keySearched')
Use CREATE OPERATOR ~#& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) and use ~#& instead ?| everything will works fine
This works for me:
jsonb_exists(some_jsonb_array,'search_value');
I would like to do search for advanced search. The Search feature has and/or for every category. User can choose any combination of and n or. Here i give the screenshot
I store the and/or into variable call $pil, $pil1,$pil2 and $pil3. And will put them in query. it's better than validate one by one every condition of and/or
So this is my query using postgresql in PHP
$query = pg_query("SELECT evaluationdate,onlinename,channel,topik,reviewername,sourceevaluation,evaluation
from AgentPerformance
where onlinename like '%".$VEOn1."%'
".$pil." reviewername like '%".$VERev1."%'
".$pil1." channel like '%".$VEChan1."%'
".$pil2."sourceevaluation like '%".$VESource1."%'
".$pil3."evaluationdate between '".$VEStart1."' and '".$VEEnd1."'");
EDIT :
The problem now, All the variables must not be empty or the query will be error. any way to trick this?
You've missed some spaces near sourceevaluation and evaluationdate
Try with this query :
$query = pg_query("SELECT evaluationdate,onlinename,channel,topik,reviewername,sourceevaluation,evaluation
from AgentPerformance
where onlinename like '%".$VEOn1."%'
".$pil." reviewername like '%".$VERev1."%'
".$pil1." channel like '%".$VEChan1."%'
".$pil2." sourceevaluation like '%".$VESource1."%'
".$pil3." evaluationdate between '".$VEStart1."' and '".$VEEnd1."'");
Simply. Use validation for each $pil whether it is empty or not. it makes me validate 4 times, but it solves the problem. The syntax error has been solved too