Mysql select where and order by - php

i got a point system that are like people can upgrade to [PRO1] user. everyones rights(pro1,pro2,user) are stored in my mysql users table. But i want to make a little feed, that shows the latest one that upgraded to [PRO1]. the upgrade code:
$insert = "UPDATE `users` SET `points` = (`points`-50) WHERE `username` = '".$username."' and points > 50";
mysql_query($insert);
if (mysql_affected_rows() > 0)
{
// other codes
$insert = "UPDATE users SET rights=' [PRO1]' WHERE `username` = '".$username."'";
mysql_query($insert);
header('location: succesupgrade.php');
}else{
echo "You don't have enough points";
}
?>
the upgrade code works fine(just incase i need to add a time/date. and tha code for where i want the"'username' wast the last to upgrade to [PRO1]" is in this code:
<?php
require("dbc.php");
$query = mysql_query("select * from users WHERE rights='[PRO1]' order by right DESC limit 1") or die(mysql_error());
while($array = mysql_fetch_array($query)) {
echo "{$array['username']}<br>";
}
?>was the last to upgrade to:
<?php
require("dbc.php");
$query = mysql_query("select * from users WHERE rights='[PRO1]' order by rights DESC limit 1") or die(mysql_error());
while($array = mysql_fetch_array($query)) {
echo "{$array['rights']}<br>";
}
?>
But that code gives me this error: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 'DESC limit 1' at line 1

order by right must be order by rights in the first query of the second code block.

That query is going to do nothing to tell you who the last user to upgrade to rights='[PRO1]'. That is just a string field. You would need some sort of datetime/timestamp field that is updated when the users rights change, by which you can make the sort.
You also don't need to do 2 queries. You have two queries doing the exact same thing.
Just do:
SELECT username FROM users WHERE rights='[PRO1]' ORDER BY update_timestamp DESC LIMIT 1
Where update_timestamp would be the field that is updated when the rights change.

The reason is because right is a used keyword, you need a back stroke to solve this :;
Like :
select * from `users` WHERE rights='[PRO1]' order by `rights` DESC limit 1

Related

Check if row exists so user cannot tamper with input

NOTE: I've edit the whole post, trying to make it clearer.
I'm terrible at getting my question clear, but this is my last try.
I got this which gets sent when clicking the button;
echo"Auto/Prijs<br><br><select name='autos'>";
echo"<br><br>";
$sql = "SELECT `garage`.`id`, `car_id`, `schade`, `naam`, `prijs` FROM `garage` LEFT JOIN `cars` ON (`garage`.`car_id` = `cars`.`id`) WHERE `user_id`=".ID." ORDER BY `id` ASC LIMIT ".($page * 10).", 10";
$sql = mysql_query($sql) or die(mysql_error());
$i = 1;
while($res = mysql_fetch_assoc($sql)){
echo"
<option value='".$res['car_id']."'>".$res['naam']."</option><br>
";
This is a dropdown, showing carnames instead of car_id's.
Now, the car_id is not unique, but refers to a car. The 'id' in the 'garage' table IS unique. Am I able to like call the 'id' too, and on sending check if that ID is actually the sent 'car_id'? Because, you can tamper the sent car_id and simply change it.
This happens on sending:
if(isset($_POST['start'])){
$prijs = $_POST['prijs'];
$carr = $_POST['autos'];
$sql = mysql_query("SELECT `id` FROM `automarkt` WHERE `seller_id`=".ID." LIMIT 1") or die(mysql_error());
mysql_query("INSERT INTO `automarkt`(`seller_id`, `prijs`, `car_id`) VALUES (".ID.", ".$prijs.", ".$carr.")") or die(mysql_error());
I'm out of idea's, and can't get clear enough on what I need to do. I need to check if the sent car_id is actually in the 'user''s garage. (Trying to do it by checking the unique entry 'id' in the 'garage' table.
Fixed it by matching rows.
$sql = mysql_query("SELECT `id` FROM `garage` WHERE `car_id`=".$carr." AND `user_id`=".ID) or die(mysql_error());
} elseif(mysql_num_rows($sql) == 0){
$msgs = bad("x");
Thanks for replies.

MySQL "Convert" doesn't seem to be working

I'm creating a database to CSV export function.
I'm using MySQL convert function to convert the date, but it doesn't seem to be working.
The error that I get is :-
string(140) "SELECT userid,firstname,lastname,email,CONVERT(VARCHAR(10),registrationdate, 101) as registrationdate from users order by userid LIMIT 0,30" 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 'VARCHAR(10),registrationdate, 101) as registrationdate from users order by user' at line 1
Code
<?php
include '../inc/inc.functions.php';
include '../dbconnector.php';
include '../dbpdo.php';
$query = "SELECT userid,firstname,lastname,email,CONVERT(VARCHAR(10),registrationdate, 101) as registrationdate from users order by userid LIMIT 0,30";
var_dump($query);
$result = mysql_query($query,$db) or die(mysql_error($db));
$array = array();
# Headers
$array[] = array("Serial Number","First Name","Last Name","Email","Registraion Date");
while($row = mysql_fetch_array($result)) {
// $array[] = $row;
$array[] = array($row['userid'],$row['firstname'],$row['lastname'],$row['email'],$row['registrationdate']);
}
array_to_csv_download($array,"records.csv",",");
?>
What might be the problem? Any suggestions would be helpful.
MySQL does not have CONVERT(..., 101), that's SQL Server's way of formatting datetimes.
In MySQL, you could use DATE_FORMAT('%m/%d/%Y', registrationdate);
SELECT userid,firstname,lastname,email,
DATE_FORMAT('%m/%d/%Y', registrationdate) as registrationdate
from users
order by userid
LIMIT 0,30

PHP Script Not erroring and not running

My code is this:
<?php
echo "Test1";
$con=mysqli_connect("Removed");
$Amount=$_GET["Amount"];
$GetType=$_GET["Type"];
var_dump($GetType);
var_dump($Amount);
$sql_query = "SELECT * FROM EventRecord WHERE EventType='$GetType' ORDER BY EventId DESC";
$sql_result = mysqli_query($con,$sql_query)
or exit(mysqli_error($con));
while($sql_row = mysqli_fetch_assoc($sql_result)){
echo $sql_row['EventId'].'<br>';
}
mysqli_close($con);
?>
For some reason, when I go to http://www.example.com/MyPhp.php?Type=Join&Amount=10, all that is outputted is "Test1string(4) string(2)".
Note: I am aware of SQL Injection vulnerabilities, however they do not affect me specifically with this code. All table structure is correct.
Additionally, how would I make it echo the top rows, as determined by how large the EventId is, but echo only the top 2, or top 3, or top 7, or top any other number, depending on what $Amount is?
Replace
$sql_result = mysqli_query($con,$sql_query)
or exit(mysqli_error($con));
With
if(!($sql_result = mysqli_query($con,$sql_query))) {
exit(mysqli_error($con));
}
See :
PHP: mysqli::$error - Manual
and PHP: mysqli::query - Manual
How about using the LIMIT to display the first $Amount results from the database?
SELECT * FROM EventRecord WHERE EventType='$GetType' ORDER BY EventId DESC LIMIT 0, $Amount
Please correct me if I your question.

Update table based on condition (While Loop)

So I am trying to update my table based on a singe parameter:
The dateEntered field must be blank.
And I want to randomly select 50 rows, and update the blank ownerID fields to "Tester"
Here is what I have:
<?php
include("includes/constants.php");
include("includes/opendb.php");
$query = "SELECT * FROM contacts WHERE dateEntered='' ORDER BY RAND() LIMIT 50";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result)){
$firstid = $row['id'];
$query2 = mysql_query("UPDATE contacts
SET ownerID = 'Tester'
WHERE id = '$firstid'");
$result2 = mysql_query($query2) or die(mysql_error());
}
?>
It will update a single record, then quit and give me:
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 '1' at line 1
The first part that selects the records works fine, its query2 that won't update all 50 records, just one. Maybe I am writing this wrong.
mysql_query needs only one time
$query2 = mysql_query("UPDATE contacts
SET ownerID = 'Tester'
WHERE id = '$firstid'");
$result2 = mysql_query($query2) or die(mysql_error());
to
$result2 = mysql_query("UPDATE contacts
SET ownerID = 'Tester'
WHERE id = '$firstid'");
These answers are spot on, so I will only add some additional information, and a suggestion. When you are querying mysql the first time, $query1 is being set to the result resource, which for
$query1 = mysql_query("UPDATE contacts SET ownerID = 'Tester' WHERE id = '$firstid'");
returns a result of 1 (Boolean TRUE), which is why your second query failed, cause "1" isn't a valid mysql query string. As Greg P stated, you can fix your current script by eliminating the secondary mysql query.
However, you could improve the script entirely, and make fewer sql calls, by using this.
<?php
include("includes/constants.php");
include("includes/opendb.php");
$query = "UPDATE contacts SET owenerID='Tester' WHERE dateEntered='' ORDER BY RAND() LIMIT 50";
$result = mysql_query($query) or die(mysql_error());

SELECT then immediately DELETE mysql record

I have a PHP script that runs a SELECT query then immediately deletes the record. There are multiple machines that are pinging the same php file and fetching data from the same table. Each remote machine is running on a cron job.
My problem is that sometimes it is unable to delete fast enough since some of the machines ping at the exact same time.
My question is, how can I SELECT a record from a database and have it deleted before the next machine grabs it. For right now I just added a short delay but it's not working very well. I tried using a transaction, but I don't think it applies here.
Here is an example snippet of my script:
<?php
$query = "SELECT * FROM `queue` LIMIT 1";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$email = $row['email'];
$campaign_id = $row['campaign'];
}
$queryx = "DELETE FROM `queue` WHERE `email` = '".$email."'";
$resultx = mysql_query($queryx) or die(mysql_error());
?>
Really appreciate the help.
If you're using MariaDB 10:
DELETE FROM `queue` LIMIT 1 RETURNING *
Documentation.
well I would use table locks
read more here
Locking is safe and applies to one client session.
A table lock protects only against inappropriate reads or writes by other sessions.
You should use subquery as follows...
<?php
$queryx = "DELETE FROM `queue` WHERE `email` IN (SELECT email FROM `queue` LIMIT 1)";
$resultx = mysql_query($queryx) or die(mysql_error());
?>
*Note: Always select only the fields you want... try to avoid select *... this will slow down the performance
run an update query that will change the key before you do your select. Do the select by this new key, whicj is known only in the same session.
If the table is innoDB the record is locked, and when it will be released, the other selects won't find the record.
Put your delete queries inside the while loop, just incase you ever want to increase the limit from your select.
<?php
$query = mysql_query("SELECT * FROM `queue` LIMIT 1") or die(mysql_error());
while($row = mysql_fetch_array($query)){
mysql_query("DELETE FROM `queue` WHERE `email` = '" . $row['email'] . "' LIMIT 1") or die(mysql_error());
}
?>
The above code would be just the same as running:
mysql_query("DELETE FROM `queue` LIMIT 1") or die(mysql_error());
Be careful using your delete query, if the email field is blank, it will delete all rows that have a blank email. Add LIMIT 1 to your delete query to avoid multiple rows being deleted.
To add a random delay, you could add a sleep to the top of the script,
eg:
<?php
$seconds = mt_rand(1,10);
sleep($seconds);
?>

Categories