Does ORDER BY and WHERE clause have different precedence? - php

I am currently fetching data using the statement
$queryfetchBookings="SELECT `id`,`sessionHeld`,`fk_student_id`,`channelName`,`video_duration`,`audio_duration`,`category`,`dateBooked`,`timeSlot`,`duration`,`category`,`studentName`,`overallRating`,`chat_duration` FROM `one_to_one_bookings` WHERE fk_co_id=".$co_id;
I now want to add an
ORDER BY `id` ASC
to the end but whatever variation I have tried results in failure.(Does not fetch data). Need advice on how to proceed.
Different variations that i have tried:

First of all, you should use prepared statements to avoid SQL injection, and not concatenating strings to your query.
You are doing wrong your concatenation in PHP, you need to add a . and some quotes:
$queryfetchBookings="SELECT `id`,`sessionHeld`,`fk_student_id`,`channelName`,`video_duration`,`audio_duration`,`category`,`dateBooked`,`timeSlot`,`duration`,`category`,`studentName`,`overallRating`,`chat_duration`
FROM `one_to_one_bookings` WHERE fk_co_id=".$co_id." ORDER BY `id` ASC";
The problem was at the end of the query:
WHERE fk_co_id=".$co_id." ORDER BY `id` ASC";

I am not sure about how the server you are using works, but in oracle it would not work because after the WHERE clause you are adding a ";". At least in oracle this would mean that the query is over, so I am guessing this is why it is not considering your last sentence.
I hope I can help :)

Related

Should you use prepared statments on LIMIT

One day I was googling to understand when a prepared statment should be used. As I searched online many claimed that you should use always prepared statments. Now the question I have is... does this also count for LIMIT? I mean it is possible (I tried) but is it really that rational? Same question on ORDER BY too.
When the database does not allow you to use a parameter on a specific location of the SQL statement you need to assemble the query on the fly, by the use of Dynamic SQL. That is... concatenating strings to get a full functioning SQL query.
Now, the trick is to make it safe against SQL Injection. To do this:
Make sure the value for LIMIT is an integer, and not something unsafe coming right from the UI like 3; DROP TABLE EMPLOYEE.
For the ORDER BY clause make sure the columns are not coming from the UI "as is"; use some kind of projection. For example, if there are 50 columns to order by, the UI can display them all, but then just send a number (from 1 to 50) to the backend; the backend receives this number and reconstitutes the ordering column(s) from it.
Normally the LIMIT parameters must be literals, not values that can be substituted for placeholders, so you would have to validate that they're integers before substituting into the string.
However, if you use PDO rather than mysqli, it allows you to perform parameter substitution in the LIMIT clause, by using the PDO::ATTR_EMULATE_PREPARES option. This is automatically enabled for a specific prepared statement if it contains parameters in this clause. See How to apply bindValue method in LIMIT clause? for the specific details.

PHP - Remove quotes in MySQL query [duplicate]

I am trying to refer to a column name to order a query in an application communicating with an Oracle database. I want to use a bind variable so that I can dynamically change what to order the query by.
The problem that I am having is that the database seems to be ignoring the order by column.
Does anyone know if there is a particular way to refer to a database column via a bind variable or if it is even possible?
e.g my query is
SELECT * FROM PERSON ORDER BY :1
(where :1 will be bound to PERSON.NAME)
The query is not returning results in alphabetical order, I am worried that the database is interpreting this as:-
SELECT * FROM PERSON ORDER BY 'PERSON.NAME'
which will obviously not work.
Any suggestions are much appreciated.
No. You cannot use bind variables for table or column names.
This information is needed to create the execution plan. Without knowing what you want to order by, it would be impossible to figure out what index to use, for example.
Instead of bind variables, you have to directly interpolate the column name into the SQL statement when your program creates it. Assuming that you take precautions against SQL injection, there is no downside to that.
Update: If you really wanted to jump through hoops, you could probably do something like
order by decode(?, 'colA', colA, 'colB', colB)
but that is just silly. And slow. Don't.
As you are using JDBC. You can rewrite your code, to something without bind variables. This way you can also dynamically change the order-by e.g.:
String query = "SELECT * FROM PERS ";
if (condition1){
query = query+ " order by name ";
// insert more if/else or case statements
} else {
query = query+ " order by other_column ";
}
Statement select = conn.createStatement();
ResultSet result = select.executeQuery(query);
Or even:
String columnName = getColumnName(input);
Statement select = conn.createStatement();
ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName);
ResultSet result = select.executeQuery(
"SELECT * FROM PERS ORDER BY " + columnName
);
will always be a new statement to the database.
That means it is, like Thilo already explained, impossible to "reorder" an already bound, calculated, prepared, parsed statement. When using this result set over and over in your application and the only thing, which changes over time is the order of the presentation, try to order the set in your client code.
Otherwise, dynamic SQL is fine, but comes with a huge footprint.

sql update statement where 2 condition apllies

This is quite a basic question, but have not found that much on-line to support.
I need to use a simple update statement in mysql (I know i should use mysqli but not yet ready for this update)
Given That I am working with a database made of a fixed number of items I want that the update apllies only when 2 conditions together are true.
my idea is something like
$sql ="update `members` set `description`='$description[$index]' WHERE id='1' AND fruit = 'banana'";
Is this the proper way of selecting the record to be updated?
Many thanks
Manu
That's how you'd do it more or less, here's a refined one:
$sql ="update `members` set `description`=? WHERE `id`='1' AND `fruit` = 'banana'";
1) See how I put the ? instead of the array? There are smart objects in PHP (read about "Prepared Statements") which allow you to put a parameter "spot" in the query and later have a value instead of it. This makes your query much more secure.
2) I added '`' around your columns. It's not mandatory, but it makes sure that your columns aren't mistaken for something else.
Yes that should work but it's safer to wrap array values in a string in brackets:
$sql ="UPDATE `members` SET `description`='{$description[$index]}' WHERE id='1' AND fruit = 'banana'";
Also make sure $description is somehow filtered or validated, before plugging it directly into the string.
NOTE: Best practice dictates that you use all caps for all SQL keywords, allowing easier differentiation between keywords and your values. Yours has half and half update and set lowercase; WHERE and AND caps, which is worse than going with all lowercase.
[edit] I agree with Daniel Saad that you should be using prepared statements here as well.

PHP/SQL fetch multiple values on SUM SQL statement

This is a bit of a complicated issue to explain but here goes:
I have an SQL statement:
SELECT
SUM(time.timein),
time.reasonforabsence
WHERE
staff.id = time.staff_id
AND
staff.department_id = department.id
AND
(staff_name LIKE '%$staffsearch%')
GROUP BY
staff.id
ORDER BY
time.dateadded
ASC;
From this statement I need to pull the values time.reasonforabsence but as this is text and the statement is grouped, I cannot seem to do this. Does anyone know if there is a way for me to pull them possibly into a PHP array.
The time.reasonforabsence has multiple possible values.
Sorry for the vagueness I am writing this in a rush. Let me know if there is anymore info needed and I will add it tomorrow.
What you can do is return an aggregated string
SELECT
SUM(time.timein),
GROUP_CONCAT(time.reasonforabsence)
...
You can optionally use DISTINCT if you don't want repeated reasons. On php you'll have split them

SQL Injection not working on SQL injection vulnerable forms?

I have the following code, which is vulnerable to SQL injection(I think?):
$IDquery = mysqli_query($connection, "SELECT `ID` FROM users WHERE username=$usernamelogin");
I don't escape the $usernamelogin, and that is not a parameterized query. This obviously needs to be fixed, you don't need to point that out, that isn't what this question is about. Before I fix it, I want to make sure I understand how an SQL injection works as well as possible. So, I tried creating a table named "droptable" and inputting the following into the username input:
x; DROP TABLE droptable;
Which I believe should input this SQL query:
SELECT `ID` FROM users WHERE username=x; DROP TABLE droptable;
However, droptable still exists, and the rows in it are untouched. Could anybody tell me why?
mysqli_query() doesn't support multiple query execution.
You don't have quotes around $usernamelogin so when you supply a string that would produce an error. Either add quotes or supply a number

Categories