How do I fix this MySQL error? - php

I have this code for a news feed and it's combined with a code for a "load more" function. The updates table is where the updates in the newsfeed exist. The username_poster is the username of the person posting an update into which displays in the newsfeed. $last_msg_id represents the id of the last post in the newsfeed to represent what to load next.
The problem I'm having is whenever my code calls to this script, it never loads it. The script works fine when I have the
username_poster IN
(SELECT user_id FROM scuela_following WHERE follower_id = '".$_SESSION['username']."')`
out of the code, but as soon as I add it in, it stops working. Any help would be greatly appreciated.
<?php
$last_msg_id=$_GET['last_msg_id'];
$sql=mysql_query("SELECT * FROM updates_table WHERE id < '$last_msg_id' AND username_poster IN
(SELECT user_id FROM scuela_following WHERE follower_id = '".$_SESSION['username']."')
ORDER BY id DESC LIMIT 5");
$last_msg_id="";
while($row=mysql_fetch_array($sql))
{
}
?>

In this SQL it looks like you're looking for a "username_poster" in your subquery, when you're only selecting "user_id."
AND username_poster IN
(SELECT user_id
FROM scuela_following
Alter the SQL to look for "user_id" instead of "username_poster", or return "username_poster" instead of "user_id" in the subquery.
And as mentioned above, you should really use queries with parameters to prevent SQL injection.

I see that you miss the session_start(); at the very top of your script.

I suspect that there is a problem here:
"... WHERE follower_id = '".$_SESSION['username']."' ..."
Firstly you are not properly escaping and may have an SQL injection vulnerability. You should use mysql_real_escape_string or parameterized queries.
Secondly, it looks like you are comparing a username (e.g. "foobar") to an ID (e.g. 10042). You probably need to join with another table that relates usernames to user IDs.

Related

PHP MYSQL Query not fetching multiple WHERE Conditions

I have a search feature that onkeydown gives out suggestions. Currently, the query only fetches from one row of the table customer_name, and I'm trying to have the id row as well to be searched for the suggestions.
so my query syntax looks likes this:
$query = "SELECT * FROM customers WHERE customer_name OR id like'%".$search."%' LIMIT 5";
But the above query will only fetches from the second table name i.e., id but not both.
What am I doing wrong here?
I could be wrong, but WHERE customer_name will always evaluate to true and thus include all records. You need to specify what customer_name should be compared to.
Correct query:
SELECT * FROM customers
WHERE customer_name LIKE '%".$search."%'
OR id LIKE '%".$search."%'
LIMIT 5;
As an important security tip, you should look into prepared statements instead of mixing data with your queries. Doing so leaves you vulnerable to SQL injection attacks.

This query on mysql is taking forever to execute

im making a simple admin module to query the database to show the results. Im using this query via php:
SELECT
*
FROM myTable
WHERE id in(SELECT
id_registro
FROM myOtherTable
where id_forma='".$id_club."' and fecha_visita Like '%".$hoy."%'
)
order by id DESC
The result shows, however, it takes very long like 2 minutes..Anyone can help me out?
Thanks!
Without seeing your database, it is hard to find a way to make it faster.
Maybe you can try to turn your WHERE IN to INNER JOIN. To something like this
SELECT * FROM myTable INNER JOIN myOtherTable
ON (myTable.id = myOtherTable.id_registro)
WHERE myOtherTable.id_forma = '$id_club'
AND myOtherTable.fecha_visita LIKE '%$hoy%'
ORDER BY myTable.id DESC
Noted that you should sanitize your variable before putting it SQL query or using PDO prepare statement.
Sub Queries takes always time, so its better to ignore them as much as possible.
Try to optimize your query by checking its cardinality,possible keys getting implemented by DESC or EXPLAIN , and if necessary use FORCE INDEX over possible keys.
and I guess you can modify your query as:
SELECT
*
FROM myTable
inner join id_registro
on (id = id_forma )
where
id_forma='".$id_club."' and fecha_visita Like '%".$hoy."%'
order by id DESC
LIKE in mysql may take a long time ,with or without index.
Do u have a very large DB?

php activerecord ORDER BY causes query to fail

I have a codeigniter project that uses php active record. there are 3 tables (users,punches,and jobs) When I run this query
$records = Punches::find_by_sql("Select * from jobs,users,punches where jobs.job_id = $job_id AND punches.job_id = $job_id AND punches.id= users.id AND NOT ISNULL(end_time) ORDER BY last_name,id ");
the query fails. If I take the order by out it works just fine. Please note I've used every variation of ORDER BY I can think of.
Since you are joining multiple tables, you need to specify which tables columns you are using when the column is not unique. In your case you need to specify which table the id column is from.
be spesific for id in your order by id, because users and punches tables have id too
$records = Punches::find_by_sql("... ORDER BY last_name, TABLENAME.id");
Thanks to whoever suggested that I run it in phpmyadmin... that helped to spot the error quickly. I needed tablename.id

My MySQL query with Count/Group By doesn't work correctly

I'm writing a PM (private messages) system in PHP for one of my projects, and I'm stuck with a single MySQL query that uses (or should be using) Count. The query would take place in a function, which is supposed to return the value of unread messages for $id user.
My table layout looks like this:
___________________________________________________________________________________
+-message_id--||--from_user--||--to_user--||--content--||--date_sent--||--is_read-+
And I wrote a query like that:
$count = mysql_query("
SELECT Count(from_user)
FROM messages
WHERE to_user='$id'
AND is_read=0
GROUP BY to_user
",$connection);
I'm not really familiar with this Count/Group By stuff, so I'm not sure about what I did wrong. I did a few Google searches, but didn't find anything which could be useful for me.
If you could help me about this little problem, that would be awesome.
Thanks! :)
Remove the GROUP BY clause:
SELECT COUNT(*)
FROM messages
WHERE to_user = '$id'
AND is_read = 0

SQL injection even when the variable is escaped [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
The sql injection will work only when my query looks like below sample
SELECT * FROM login WHERE id = $my_id_va;
Assume if my query is
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
Than I will get following error
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'order by id desc' at line 1
So, this 1 or 1=1; SHOW TABLES will not work, correct?
My site was hacked successively many times.
I want one quick answer: When my query looks like the following one, what ways or which types of query can they use to hack my site?
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
What are the ways to execute the show table in the following query
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
I am also using escaping function to handle the query string values, like mysql_real_escape_string($my_id_va). Yes, obviously this for single related hack, but not sure.
Added some more
SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC
but show table not worked
If you are using PHP5, use parametarized query, use PDO.
Int cast
If id is a number, you can int-cast your variable as well. Integers are safe to use:
$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";
mysql_real_escape_string
If you want to pass a string, you can, and should, use mysql_real_escape_string, but this function escapes only those characters that are inside the string. You will still need to add quotes around the string, so:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = $x";
.. will result in the query: select * from Table where id = hello. This is obiously not a valid query, since hello should be in quotes.
Change the query to:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = '$x'";
.. and everything works fine. You add the quotes around, and mysql_real_escape_string takes care of special characters inside the string, if any.
Parameters
Another solution is to use parameterized queries. This can by done using MySQLi or PDO. The advantage is that you only tell your database where a variable should be inserted, and the database takes care of the escaping yourself.
It also may add a performance benefit, because these queries could be cached without their parameters, make a more efficient use of the query cache. This doesn't really work yet in current versions of MySQL, though.
You are right that 1 or 1=1; SHOW TABLES will give a syntax error but this will work:
1 or 1=1 --
The -- comments out the rest of the query.
In your case the value is an integer so instead of using mysql_real_escape_string you can use intval.
If you set $my_id_va to:
1 or 1=1; SHOW TABLES --
The -- will comment out the rest of the command, effectively terminating it.
I'm not sure what effect mysql_real_escape_string will have on the query. What you should be doing is parameterized queries.
1. First query somehow secured
$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));
2. Second query somehow secured
$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC",
mysql_real_escape_string($start_date),
mysql_real_escape_string($end_date));
Read the docs about sprintf if you don't understand it.
However, as others have said, it would be very very secure if you would use parameterized queries with a class such as PDO or MySQLi.

Categories