Bind Parameters with Jsonb ?| operator in Doctrine2 using Postgres - php

I'm having an issue when using bind parameters in my DQL statement.
I've created a JSONB DBAL data type and a FunctionNode called JSON_CONTAINS_ANY() function. The final query that I want is:
SELECT * from Cache where content->'status' ?| ['started','inprogress'];
My DQL statement looks as follow:
$dql = "SELECT e FROM Entity e WHERE JSON_CONTAINS_ANY(content, 'status', :statusList";
$dql->setParameter('statusList',$statusList, Jsonb::JSONB);
Question:
The problem is the the ?| operator gets treated as a parameter expansion index and screws up my queries. Any ideas on how to handle this?

I don't know if my answer will be relevant, I see the question was asked 6 years ago, but, more elegant solution appeared literally 2 years ago, then can someone help. You can read in detail at this link https://wiki.php.net/rfc/pdo_escape_placeholders
from the description I will take out that now ? you can get screened in this way ?? as described in:
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.
$stmt = $pdo->prepare('SELECT * FROM tbl WHERE json_col ?? ?');
$stmt->execute(['foo']);

Related

How to use LIKE and prepared statements at the same time? [duplicate]

This question already has answers here:
Combine PHP prepared statments with LIKE
(8 answers)
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 1 year ago.
I am creating a bot and the user can enter name of a movie and results should show up by searching inside a SQL table and find the right movies name so I used prepared statements in PDO but I want to when a user type the incomplete name of a movie it shows up so I want it to be case insensitive and also find matches.
I am using mysql dirver.
before this the SQL query was like this
also noting this is a string inside a PHP script
"SELECT * FROM movies WHERE name = :name LIMIT 5"
but then I thought to use the way that I explained to you above and I know it isn't case insensitive.
"SELECT * FROM movies WHERE name LIKE :name" . "'%' LIMIT 5"
but I don't think this will work properly and fine so how should I write this query to work as I explained at the beginning?
Should use different keywords like REGEXP ?
Let me assume that you are using MySQL (based on the regexp reference).
You can then use:
WHERE name LIKE CONCAT(:name, '%')
In other databases you can use the standard string concatenation operator, ||.
Note: This is often handled at the application level, so :name is given the '%' in the application. Then your original code works.
A similar approach would work for a regular expression, but the logic would be:
WHERE name LIKE CONCAT('^', :name)

MySQL SELECT * FROM table WHERE name LIKE (?) OR owner LIKE (?); [duplicate]

This question already has answers here:
PHP PDO prepared statement -- MySQL LIKE query
(3 answers)
Closed 6 years ago.
As you can see in the title, I have a table that I want to take use of in a website I have.
This is how the MySQL statement looks like now: SELECT * FROM bth_nav WHERE name LIKE (?) OR owner LIKE (?);
On my website I want to either search for name or owner. Right now I can only search for name but not owner. This is why I'm asking for help, I've tried to rewrite the statement but however I do it i can only search for one of them.
Thanks in advance.
The answer will be a little more complicated then you would expect.
I see question marks in your query, this way I can assume you're using prepared statements (which is good!).
Your old statement was using 1 value (for the name), and now you want to use 2.
You have some options for this to work.
The easiest one would be that you bind the value twice, but that's not the nicest way.
A better way would be to name your parameters, like this:
SELECT * FROM bth_nav WHERE name LIKE (:nameOwner) OR owner LIKE (:nameOwner);
Hence that I use the same name for both parameters here. Now you can bind the value to the named parameter with bindValue, and you need do this only once.

Differences between using ? and :param in prepare statement

Let's say I want to select records where Id = 30. Prepared statements allow two ways of binding parameters:
question marks
$id = 30;
$q = $conn->prepare("SELECT * FROM pdo_db WHERE id > ?");
$q->execute(array($id)); // Here above ID will be passed
named parameters
$sth = $conn->prepare("SELECT `id`, `title` FROM `pdo_db` WHERE `id` > :id");
$sth->execute(array(
':id' => 30
));
Both are working fine and give accurate results but I am not able to get the exact differences between these two nor when I should use one or another?
Question mark parameters are called positional parameters.
Parameters defined with : and a name are called named parameters.
The rule is that you can't mix the two in your prepared statement.
Positional parameters work in a simple way - if you have two positional parameters, you can specify an array with two elements. Array values will be bound in order as they appear in the array.
Named parameters are a bit trickier, they don't have to be bound in order they appear. You can also repeat one named parameter multiple times in the statement, but you can bind it only once to pass the value - that last part works when PDO is set to emulation via $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, TRUE);.
This seesm to be more of a preference based question as there isn't a strict right or wrong answer.
Personally I avoid ? as it's tightly tied to the order of parameters. Although theoretically you shouldn't be able to mess this up by adding or removing binding a single binding, it just seems like it's asking for trouble. It is (slightly) less work though.
:name is more concise and is tightly bound to the identification of bindings, not arbitrarily to the order. It involves a (tiny) bit more work but it is much easier to debug, and less prone to mistakes.
I prefer being (slightly) concise over writing (slightly) less code.
These are different placeholders
? -- > question mark placeholders
:name --> named Placeholders
The difference between named and question mark placeholders is that with question mark placeholders you'll have to take care about the order in which they will be bound to the query.

Is there a way to use PDO with a dynamic column name in an UPDATE query? [duplicate]

This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 8 years ago.
It's a little relative to the question I asked here
(PDO adds the apostrophe to the mySQL query) but this time column name is a parameter.
Not working PDO example would be like this:
"UPDATE tbl SET :COL1 = NOT :COL1;"
sure solution like this:
"UPDATE tbl SET $COL1 = NOT $COL1;" // works (but it's not PDO)
but why
"UPDATE tbl SET $COL1 = NOT :COL1;" // does not ??
while
"UPDATE tbl SET $COL1 = :VAL_COL1;" // is ok if I first get and negate COL1 value...
In a prepared statement, a parameter is a constant value that will be passed into the query without affecting how the query will be run. This allows the database to "prepare" the query ahead of time and figure out how it will be executed even without knowing the exact values that will be used.
Using this definition, a query like this does not have any parameters, and so the PDO and non-PDO versions of the query will look the same. Your working (first) example is as good as you're going to get. In fact, I'd claim that your first example actually is the PDO version.
To use a non-database example, a prepared statement is very much like a function in a programming language such as PHP. A function accepts parameters and uses their values, but (in normal circumstances) the parameters are not lines of code that will be run. The same code is run regardless of what the parameter values are - the function code itself is not changed by the parameters.
No. You cannot bind table names or column names as parameters. You can only bind values as parameters.
See more here: Can PHP PDO Statements accept the table or column name as parameter?

search those records which have column value with & in it

I have a problem in my website, I'm trying to fetch some data from a table that has courses names. I search by the name of that course. some of the names contain '&' in them, for example "Formal Languages & Automata" and I need to fetch all the records related to this course.
When I try the below SQL statement, it fails in getting what I want:
SELECT * FROM tablename WHERE course = 'Formal Languages & Automata'
The query searches for "Formal Languages " only and neglects the & and anything after it.
Does anyone have a solution to this?
Thanks
My guess is that this could happen in is if you're passing the value you're searching by in a GET query string or a POST request body without URL-encoding it, thus when PHP receives the request, the part after & is considered the next variable in the request. In case you make the request from PHP, you need to use urlencode() and if it's in Javascript, it's the encodeURIComponent function.
You should escape the ampersand (&) character in your string:
SELECT * FROM tablename WHERE course = 'Formal Languages \& Automata'
You can use LIKE
SELECT * FROM tablename WHERE course LIKE 'Formal Languages%'
This statement will find every course that begins with 'Formal Language' and it can have any characters in the end.
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like
More about string comparsion can be found at link above. Also before puting some data to query you should escape it or use prepared statements and binding parameters which engines that have already escaping built in. For example mysqli, pdo.
Example PDO
$sth = $dbh->prepare('SELECT * FROM tablename WHERE course = :search');
$sth->bindParam(':search', 'Formal Languages & Automata', PDO::PARAM_STR);
$sth->execute();
More info about PDO here

Categories