PHP MySQL max() function producing 5 - php

I am working on a survey created by PHP and MySQL. So the issue is, I am trying to create a ResponseID, which is an ID specific for every person submitting the survey. So the code was created to add 1 to the existing max value from the ResponseID column. Here's the code:
//Response ID creation
$query = "SELECT max(ResponseID) FROM survey";
$res = mysql_query($query);
$RID = $res+1;
I know I can condense it, but here's the problem: I already entered one item on the table with the ResponseID of 1. When I tested the survey with different answers, the next ResponseID was 5. It should have been 2. So I tested again to see if it would produce 6 next time.
Unfortunately, it produced 5 again. I had my PHP guru looked it over and he said the coding was correct and it should be something from the database. I didn't set anything in the ResponseID except for it being an int. So why is it producing a 5? If anyone could please tell me how to go about fixing it, that would be super cool of you.
I am somewhat new to PHP.

$res will be a mysql statement handle, NOT the result of the query. you still have to actually FETCH a row from this $res result to access the value of the max() function in the query.
This handle probably internally has identifier #5, which is why you're getting that "odd" result.
The code should be:
$sql = "SELECT MAX(responseID) AS max ...";
$result = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_assoc($result);
$RID = $row['max'] + 1;

$res is a resource, not the value of the query, please read the manual: http://nz.php.net/manual/en/function.mysql-query.php

Why don't you use an AUTO_INCREMENT column and retrieve the new value using mysql_insert_id?

You need to use an AUTO_INCREMENT column for this. The problem is that if two instances of the PHP script are running at the same time (extremely likely assuming you're using a multithreaded server like Apache), then you could have a case like this:
|PHP #1 | PHP #2 |
=================================
|Accept client |(waiting) |
|SELECT MAX... |(waiting) |
|Send to MySQL | Accept client |
|(waiting) | SELECT MAX... |
|(waiting) | Send to MySQL |
|Get response 4 |Get response 4 | //Nothing inserted yet, max is still 4
|Try to insert 5| (waiting) |
|Succeeded | (waiting) |
|(waiting) |Try to insert 5|
| ... | Failed! |
(This in addition to what Dagon said)

Use $row = mysql_fetch_assoc($res) to get the resulting row from your query.
See mysql_fetch_assoc().

The reason why you are not getting the correct value is because mysql_query doesn't return a value, it returns a resource.
Try this instead:
//Response ID creation
$query = "SELECT max(ResponseID) FROM survey";
$res = mysql_query($query);
if($res !== FALSE) $res = mysql_fetch_array($res); // If $res === FALSE, something went wrong
$RID = $res[0] + 1;
Also I suggest you to use AUTO_INCREMENT on the ResponseID field, this makes your life a lot easier :)

i'm not really sure if i understood ur problem but if u wanna generate a response ID specific to every user or every survey posted, then what u can do is use auto_increment for the response ID. the response id will be incremented every time a new survey is posted. also get the last id posted using mysql_insert_id to get the last id posted.
so u can get the last id using
$last_id = mysql_insert_id ();
u need to put that statement right after ur query. that way u can get the last id.

Related

SQL PHP Search column name with value

Ok so I have a db of Users (ID) and their T or F results to different Hobbies. So something like this, excuse the formating I didn't know how to space it.
ID | swimming | running | rock climbing | learning to program.
user1 T F T T
user2 F T T F
OK I wanted to do a SQL search where I return all Column names of a table, if the value of that column is "T" where the ID is the users ID.
so if the ID is user1, I return swimming, rock climbing, learning to program.
Now I couldn't figure out how to do this with SQL so I figured I could try do this manually with PHP.
So I tried something like this.
$stmt = $this->con->prepare("SELECT swimming, running, rock,
program FROM mytablehere WHERE ID = ?");
$stmt->bind_param("s", $ID); // specific ID is went in via here
$stmt->execute();
$stmt->bind_result( $swimming, $running, $rock, $program);
$stmt->fetch();
$user = array();
if($swimming == "T"){
$swimming ="swimming";
$user['swimming'] = $swimming; }
...
return $user;
So the idea is it would find the binds that are "T" and insert them into the user array, and leave the ones that are "F" out.
However my postman tells me, no data is found.
So my question is how do do I get this sort of function. Is there an SQL search to make this easier or how do I need to approach my PHP code differently.
Can I not if then the bind $swimming or do I have to bind them all to one array, and then return a different array at the end?
if($user['swimming'] == "T"){
$hobby['swimming'] = "swimming"; }
return $hobby
there should really be an easier way to do this. If anyone has an sql search that would be great. But this will allow you to do it via php. I was having issues with my postman which was stopping me from getting data, but once I did the code up top will just give you an useless mess. This will return only the column names but it has to be done manually.

How to get a SUM of all parameters in the single column of database

I need to get a SUM off all numerical entries in one of the tables of my DB
id | parameter
--------------
1 | 5
2 | 1
3 | 11
4 | 3
My php is:
$total = 'SELECT parameter FROM resource_table';
$res = $db->prepare($total);
$res->execute();
while($row4 = $res->fetch()) {
$count_sum1[$row4['parameter']][] = $row4;
}
$count_sum = array_sum( $count_sum1 );
print<<<END
$count_sum
END;
this is not working, as I can guess I am not doing something correctly.
Please help
Thanks for your help in advance
Let the database do the work:
SELECT SUM(parameter) FROM resource_table
In case you want to stick to php:
<?php
// code
while($row=$res->fetch())
$count_sum+=row["parameter"];
// code
?>
Yes, database engine supports simple operations, such as SUM(), AVG(), MIN() and lot of others... so actually you are able to do some basic operation on the specific engine. Read a documentation to your database engine, because you could use MySql, MSSQL, or plenty of others and every use its own type of functions.
But I suppose that you use MySQL, so the function is simply SUM():
SELECT SUM(parameter) FROM tableName;

how to trace duplicate data

I would like to ask something here.
now I make form that insert data into table.
this table kemaskini that already have
+------+----------+----------+
| no | Item | kuantiti |
+------+----------+----------+
| 1 | Speaker | 10 |
+------+----------+----------+
| 2 | Laptop | 10 |
+------+----------+----------+
| 3 | Mouse | 10 |
+------+----------+----------+
when I type "Speaker" in form then I submit it.
it trace and say try again. it because already have.
coding that I write here. it only trace row 1 of table kemaskini.
when I type "Laptop" in form then I submit it.
it insert normally.
i more thing how I can trace "Speaker" and "speaker" are same.
if (isset($_POST['submit']))
{
$result = mysql_query("SELECT Item FROM kemaskini");
$test = mysql_fetch_array($result);
$trace=$test['Item'];
if($_POST['Item']==$trace)
{
echo "Try Again";
}
else
{
$item=$_POST['Item'] ;
$kuantiti= $_POST['kuantiti'] ;
mysql_query("INSERT INTO `kemaskini`(Item,kuantiti)
VALUES ('$item','$kuantiti')");
header("Location: kemaskini.php");
}
}
The reason for that is because you are not looping the result from mysql_fetch_array() that is why you are only checking for the first value of the result. If you don't want to Iterate, you can change the query into:
$itemToSearch = "Speaker";
$result = mysql_query("SELECT COUNT(*) result
FROM kemaskini
WHERE Item = '$itemToSearch'")
which will give you the total number of items found,
$test = mysql_fetch_array($result);
$trace = $test['result'];
if($trace > 0)
{
echo "Try Again";
}
else
{
// insert value
}
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
Regarding, how can you trace "Speaker" and "speaker" are the same, you can use the upper() or lower() function that most database engines support. I don't work with mysql so I am going on an assumption here. Your check would be something like this:
select count(*) records
from kemaskini
where lower(item) = 'speaker'
Having said that, I have to warn you that using functions in the where clause like this make your queries run slower.
If JW's comment about PreparedStatements includes using query parameters (I don't work with php either), it's very good advice. Not only do they increase the security of your applications, but they escape special characters such as apostrophes. Since you are doing a character search, you would not want your query to crash if the user submitted something like "Dave's keyboard" to your application.

MySQLi Update is not working properly

I am trying to update one of my row with PHP using MySQLi and if I refresh PHPMyAdmin less than 1 second after update it's sucessfull but if I only check the data 2 seconds+ after the update it doesn't update.
For exemple:
'UPDATE orders SET MachineID = '.$id.' WHERE OrderID = '.$OrderID.
'AND ProductID = '.$ProductID
Does not work unless I refresh quickly but...
'UPDATE orders SET MachineID = 2 WHERE OrderID = 4 AND ProductID = 12'
Will work no matter how long after I refresh. (Those are the data I normaly use to test.)
So I though it would be my variables, but I'm using them almost 10 times before this part of the code in other queries and it works perfectly.
I tried to trim() the variable and it did not help.
I also tried to use mysqli_real_escape_string() with no success.
mysqli_error() is not giving me anything.
mysqli_affected_rows() is giving me "1" which is what it is suppose to be.
And the weird part is if I execute 'SELECT MachineID FROM orders WHERE OrderID = 4 AND ProductID = 12', it gives me the updated answer even if phpMyAdmin does not update the data.
There is no other code after this, so nothing that could "reverse" the update.
A normal "test" ouput looks like this:
Edit: This it what the browser outputs.
ID: "2" //$id
OrderID: "4" //$OrderID
ProductID: "12" //$ProductID
UPDATE orders SET MachineID = 2 WHERE OrderID = 4 AND ProductID = 12 //Query
boolean true //Result var_dump
1 //Number of rows affected
2 //Machine ID
Note: The quotes are not part of the variables.
Edit: This is the PHP code
$query = 'UPDATE orders SET MachineID = '.$id.' WHERE OrderID = '.$OrderID.' AND ProductID = '.$ProductID;
echo 'ID: "'.$id.'"<br/>
OrderID: "'.$OrderID.'"<br/>
ProductID: "'.$ProductID.'"<br/>'.$query.'<br/>';
$res = $db->query($query);
var_dump($res);
echo mysqli_affected_rows ($db).'<br/>';
$result = $db->query('SELECT MachineID FROM orders WHERE OrderID = 4 AND ProductID = 12');
$result = $result->fetch_array();
echo $result[0];
I really don't understand why it would work in the file and after a quick refresh but not if it takes to long to retreive the data. It's like it would reset after a certain amount of time if it's not fetch.
I've been working on this for almost 2 days now I have no idea why it's not working. This is some pretty simple SQL query.
Edit: I've look into MySQL binary logs and it seems that I'm updating it back to 1 every time. The only way this could be happening is if the file would run twice, but if it runs twice why would the output be there only once ?
Edit: Ok, so it seems like the problem comes from Google Chrome. I've tested it on IE and it works. For some reason Chrome would be running the file twice.
Ok so I was able to find the problem and fix it.
Problem:
The problem was the famous "favicon" bug with Chrome which is trying to get the icon even if it doesn't exist, therefore the file is called twice.
Fix:
Since this file was meant to be called through an Ajax call the bug is not triggered since Chrome will not try to look for the "favicon". I basicly fixed the bug by testing it how it was supposed to be run and not just testing the file itself.

joomla-php mysql not updating a record with data from previous query

I'm counting the right answers field of a table and saving that calculated value on another table. For this I'm using two queryes, first one is the count query, i retrieve the value using loadResult(). After that i'm updating another table with this value and the date/time. The problem is that in some cases the calculated value is not being saved, only the date/time.
queries look something like this:
$sql = 'SELECT count(answer)
FROM #_questionsTable
WHERE
answer = 1
AND
testId = '.$examId;
$db->setQuery($sql);
$rightAnsCount = $db->loadResult();
$sql = 'UPDATE #__testsTable
SET finish = "'.date('Y-m-d H:i:s').'", rightAns='.$rightAnsCount.'
WHERE testId = '.$examId;
$db->setQuery($sql);
$db->Query();
answer = 1 means that the question was answered ok.
I think that when the 2nd query is executed the first one has not finished yet, but everywhere i read says that it waits that the first query is finished to go to the 2nd, and i don't know how to make the 2nd query wait for the 1st one to end.
Any help will be appreciated. Thanks!
a PHP MySQL query is synchronous ie. it completes before returning - Joomla!'s database class doesn't implement any sort of asynchronous or call-back functionality.
While you are missing a ';' that wouldn't account for it working some of the time.
How is the rightAns column defined - eg. what happens when your $rightAnsCount is 0
Turn on Joomla!'s debug mode and check the SQL that's generated in out the profile section, it looks something like this
eg.
Profile Information
Application afterLoad: 0.002 seconds, 1.20 MB
Application afterInitialise: 0.078 seconds, 6.59 MB
Application afterRoute: 0.079 seconds, 6.70 MB
Application afterDispatch: 0.213 seconds, 7.87 MB
Application afterRender: 0.220 seconds, 8.07 MB
Memory Usage
8511696
8 queries logged.
SELECT *
FROM jos_session
WHERE session_id = '5cs53hoh2hqi9ccq69brditmm7'
DELETE
FROM jos_session
WHERE ( TIME < '1332089642' )
etc...
you may need to add a semicolon to the end of your sql queries
...testId = '.$examID.';';
ah, something cppl mentioned is the key I think. You may need to account for null values from your first query.
Changing this line:
$rightAnsCount = $db->loadResult();
To this might make the difference:
$rightAnsCount = ($db->loadResult()) ? $db->loadResult() : 0;
Basically setting to 0 if there is no result.
I am pretty sure you can do this in one query instead:
$sql = 'UPDATE #__testsTable
SET finish = NOW()
, rightAns = (
SELECT count(answer)
FROM #_questionsTable
WHERE
answer = 1
AND
testId = '.$examId.'
)
WHERE testId = '.$examId;
$db->setQuery($sql);
$db->Query();
You can also update all values in all rows in your table this way by slightly modifying your query, so you can do all rows in one go. Let me know if this is what you are trying to achieve and I will rewrite the example.

Categories