I have the following line:
$reset = "UPDATE pidgeon SET obt='" . $hour . "' WHERE tag='" . $tag . "'";
Which updates just fine. However I need to update an additional row (kill) and I keep getting syntax errors. I've tried the following:
$reset = "UPDATE pidgeon SET obt='" . $hour . "', kill='1' WHERE tag='" . $tag . "'";
$reset = "UPDATE pidgeon SET kill='1', obt='" . $hour . "' WHERE tag='" . $tag . "'";
$reset = "UPDATE pidgeon SET obt='" . $hour . "', kill='" . $num . "' WHERE tag='" . $tag . "'";
I've even done 2 separate UPDATE queries and I get the same syntax error message. I've narrowed it down to the system having issue with the kill row but I'm not sure what's the issue. I've tried setting kill as INT, SMALLINT, BOOL, even CHAR and trying to use 't/f' as values for it. I still get a syntax error. Any suggestions?
KILL is a reserved keyword, so you'll have to enclose it in backticks, like so:
$reset = sprintf("UPDATE pidgeon SET `kill`='1', obt='%s'
WHERE tag='%s'", $hour, $tag);
Kill is actually a syntax, you can't use them directly.
Just replace kill with another name.
Related
I have this query which works successfully in one of my PHP scripts:
$sql = "UPDATE Units SET move_end = $currentTime, map_ID = $mapID, attacking = $attackStartTime, unit_ID_affected = $enemy, updated = now() WHERE unit_ID IN ($attackingUnits);";
$attackingUnits is an imploded array of anywhere between 1 - 100 integers.
What I'd like to do is also add arrays with different values for $currentTime and $mapID which correspond with the values for $attackingUnits. Something like this:
$sql = "UPDATE Units SET move_end = " . $attackingUnits['move_end'] . ", map_ID = " . $attackingUnits['map_ID'] . ", attacking = $attackStartTime, unit_ID_affected = $enemy, updated = now() WHERE unit_ID IN ($attackingUnits);";
Obviously that won't work the way I want it to because $attackingUnits['move_end'] and $attackingUnits['map_ID'] are just single values, not an array, but I'm stumped as to how I can write this query. I know I can one query for each element of $attackingUnits, but this is precisely what I'm trying to avoid as I'd like to be able to use one UPDATE for as many elements as required.
How would I write this query?
The key parts of the PHP script are:
$attackStartTime = time(); // the time the units started attacking the enemy (i.e. the current time)
// create a proper multi-dimensional array as the client only sends a string of comma-delimited unitID values
$data = array();
// add the enemy unit ID to the start of the selectedUnits CSV and call it allUnits. we then run the same query for all units in the selectedUnits array. this avoids two separate queries for pretty much the same columns
$allUnits = $enemy . "," . $selectedUnits;
// get the current enemy and unit data from the database
$sql = "SELECT user_ID, unit_ID, type, map_ID, moving, move_end, destination, attacking, unit_ID_affected, current_health FROM Units WHERE unit_ID IN ($allUnits);";
$result = mysqli_query($conn, $sql);
// convert the CSV strings to arrays for processing in this script
$selectedUnits = explode(',', $selectedUnits);
$allUnits = explode(',', $allUnits);
while ($row = mysqli_fetch_assoc($result)) {
$data[] = $row;
}
$result -> close();
$increment = 0; // set an increment value outside of the foreach loop so that we can use the pointer value at each loop
// check each selected unit to see if it can validly attack the enemy unit, otherwise remove them from selected units and send an error back for that specific unit
foreach ($data as &$unit) {
// do a whole bunch of checking stuff here
}
// convert the attacking units (i.e. the unit ids from selected units which have passed the attacking tests) to a CSV string for processing on the database
$attackingUnits = implode(',', $selectedUnits);
// update each attacking unit with the start time of the attack and the unit id we are attacking, as well as any change in movement data
// HERE IS MY PROBLEMATIC QUERY
$sql = "UPDATE Units SET moving = " . $unit['moving'] . ", move_end = " . $unit['move_end'] . ", map_ID = " . $unit['map_ID'] . ", attacking = $attackStartTime, unit_ID_affected = $enemy, updated = now() WHERE unit_ID IN ($attackingUnits);";
$result = mysqli_query($conn, $sql);
// send back the full data array - should only be used for testing and not in production!
echo json_encode($data);
mysqli_close($conn);
OK, after some more web research I found a link that helped me out:
https://stuporglue.org/update-multiple-rows-at-once-with-different-values-in-mysql/
I updated his code to mysqli and after a lot of testing, it works! I can now successfully UPDATE hundreds of rows with one query, rather than sending hundreds of small updates via PHP. Here are the relevant parts of my code for anyone who's interested:
$updateValues = array(); // the array we are going to build out of all the unit values that need to be updated
// build up the query string
$updateValues[$unit["unit_ID"]] = array(
"moving" => $unit["new_start_time"],
"move_end" => $unit["new_end_time"],
"map_ID" => "`destination`",
"destination" => $unit["new_destination"],
"attacking" => 0,
"unit_ID_affected" => 0,
"updated" => "now()"
);
// start of the query
$updateQuery = "UPDATE Units SET ";
// columns we will be updating
$columns = array("moving" => "`moving` = CASE ",
"move_end" => "`move_end` = CASE ",
"map_ID" => "`map_ID` = CASE ",
"destination" => "`destination` = CASE ",
"attacking" => "`attacking` = CASE ",
"unit_ID_affected" => "`unit_ID_affected` = CASE ",
"updated" => "`updated` = CASE ");
// build up each column's CASE statement
foreach ($updateValues as $id => $values) {
$columns['moving'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['moving']) . " ";
$columns['move_end'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['move_end']) . " ";
$columns['map_ID'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['map_ID']) . " ";
$columns['destination'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['destination']) . " ";
$columns['attacking'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['attacking']) . " ";
$columns['unit_ID_affected'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['unit_ID_affected']) . " ";
$columns['updated'] .= "WHEN `unit_ID` = " . mysqli_real_escape_string($conn, $id) . " THEN " . mysqli_real_escape_string($conn, $values['updated']) . " ";
}
// add a default case, here we are going to use whatever value was already in the field
foreach ($columns as $columnName => $queryPart) {
$columns[$columnName] .= " ELSE `$columnName` END ";
}
// build the WHERE part. since we keyed our updateValues off the database keys, this is pretty easy
// $where = " WHERE `unit_ID` = '" . implode("' OR `unit_ID` = '", array_keys($updateValues)) . "'";
$where = " WHERE unit_ID IN ($unitIDs);";
// join the statements with commas, then run the query
$updateQuery .= implode(', ', $columns) . $where;
$result = mysqli_query($conn, $updateQuery);
This will significantly reduce the load on my database as these events can happen every second (think of hundreds of players at once, attacking hundreds of enemy units with hundreds of their own units). I hope this helps someone out.
Hey all i am created 2 random numbers like so:
$firstlink = intval(mt_rand(100, 999) . mt_rand(100, 999) . mt_rand(1, 9) . mt_rand(100, 999)); // 10 digit
$secondLink = intval(mt_rand(1000, 999) . mt_rand(1, 999) . mt_rand(10, 99) . mt_rand(100, 999));
And this is my insert code:
$result = mysql_query("INSERT INTO userAccount
(Category,Fname,LName,firstlink,secondLink,AccDate)
VALUES ( '" . $cat . "',
'" . $fname . "',
'" . $lname . "',
" . $firstlink . ",
" . $secondLink . ",
'" . date('Y-m-d g:i:s',time()). "');");
It has no errrs and it places the data into the mysql database. However, its always the same number for BOTH firstlink and secondLink no matter who i add to the database and i have no idea why its doing it!
The datatype for both rows is INT(15)
Remove intval and all will work fine.
$firstlink = mt_rand(100, 999) . mt_rand(100, 999) . mt_rand(1, 9) . mt_rand(100, 999); // 10 digit
32 bit systems have a maximum signed integer range of -2147483648 to 2147483647. With intval you got 2147483647 mostly.
You can simplify your code and improve the randomness of the code like this:
$firstlink = mt_rand(10000,99999) . mt_rand(10000,99999);
$secondLink = mt_rand(10000,99999) . mt_rand(10000,99999);
echo "INSERT INTO userAccount
(Category,Fname,LName,firstlink,secondLink,AccDate)
VALUES ( '" . $cat . "',
'" . $fname . "',
'" . $lname . "',
" . $firstlink . ",
" . $secondLink . ",
'" . date('Y-m-d g:i:s',time()). "');"
PHPFiddle: http://phpfiddle.org/main/code/6nf-wpk
This will build your random 10-digit code by making two random 5 digit codes and joining them together. Is is simpler and easier to follow with less parts making it up. It had to be done with two mt_rand()s because the maximum number possible is 2147483647. For each mt_rand() function you're using, you're preventing a 0 from being the first digit in that section of the number, because you're starting the first digit at between 1 and 9.
If you don't care about the first number being only a 1 or 2 (and never being 3-9 or 0) you can simply use
$firstlink = mt_rand(1000000000,2147483647); // random 10 digit number
$secondLink = mt_rand(1000000000,2147483647); // random 10 digit number
As general coding tips:
Be consistent with how you name variables. You have a lowercase "L" in "$firstlink" and a capital "L" in "$secondLink". PHP is case-sensitive and you'll end up using the wrong name and getting unexpected (blank) results elsewhere in your program.
Be be careful never to put any user-provided data into a SQL command without protecting against SQL Injection attacks. Use parameterized queries as a rule. See How can I prevent SQL injection in PHP? for more details and examples.
I need to round a result of a SQL round in a table array output. I can't figure out the syntax...
$result = mysql_query("SELECT `Energ_Kcal`*`yield`*`qty` AS `cal` FROM allinnot a
WHERE `own_id` = $user->id");
echo "<tr><td>" . $row['Shrt_Desc'] . "</td><td> " . $row['desc'] . "</td><td>" . $row['cal'] . " cal</td></tr>";
cal returns a value with many numerals beyond the decimal. I just need it to show a whole rounded integer. I tried ROUND(), but I must be putting it in the wrong place.
general syntax
ROUND( expression, 2 )
The ROUND should go around the values, try this:
$result = mysql_query("SELECT ROUND(`Energ_Kcal`*`yield`*`qty`,2) AS `cal` FROM allinnot a
WHERE `own_id` = $user->id");
echo "<tr><td>" . $row['Shrt_Desc'] . "</td><td> " . $row['desc'] . "</td><td>" . $row['cal'] . " cal</td></tr>";
You could also check out PHP's round() or, possibly from your description int_val().
My apologies I can not give the source for the $db class.
Why does this line of PHP in between the () give e an error?
$q = $db->sqlQuery("SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) " OR cell = " . $db->decrypt($cell) ");
You're missing a concatenation operator after $email) and an errant "
However, please stop writing queries via string substitution and move to prepared statements ASAP.
You have some syntax errors. Here 's the correct line:
$q = $db->sqlQuery("SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) . " OR cell = " . $db->decrypt($cell));
$q = $db->sqlQuery("SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) " OR cell = " . $db->decrypt($cell) ");
misses a concatenator after $db->decrypt($email)
and there is an extra " before );
$q = $db->sqlQuery("SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) . " OR cell = " . $db->decrypt($cell) );
You have an extra " in the end. And a missing concatenation operator.
"SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) . " OR cell = " . $db->decrypt($cell)
Also, I don't know what your decrypt method does, but if $email and/or $cell are strings, you should mark them as a string in the SQL statement (put ' around them).
Honestly, you should look into using PDO and prepared statements. It would clean up this mess.
You are missing concatenation operator and have extra quote in the end of the query. The correct code would be:
$q = $db->sqlQuery("SELECT * FROM realsteal WHERE email = " . $db->decrypt($email) . " OR cell = " . $db->decrypt($cell));
I am trying to use PHP to update column data but I am receiving a division by zero error.
mysql_query('UPDATE personas SET toolbar_id=\'' . $result . '\' WHERE download_ff LIKE concat('%',\'' . $result . '\','%')');
echo mysql_error($link);
printf("Records inserted: %d\n", mysql_affected_rows());
Ive tried a few ways to concat the $result but it is all resulting in a division by zero error. Help!
Your problem is right here:
concat('%',\'' . $result . '\','%')
The % ends out outside the string so PHP is interpreting it as a modulus operation and the strings on both sides of the modulus will be zeros in a numeric context, the result is that you're trying to 0 % 0 and you get your "division by zero" error.
Try escaping the inner single quotes:
concat(\'%\',\'' . $result . '\',\'%\')
Or, create a $like_result in your PHP that includes the percent signs in the string and then do this:
mysql_query('UPDATE personas SET toolbar_id=\'' . $result . '\' WHERE download_ff LIKE \'' . $like_result . '\';
You are using mysql_real_escape_string too, right?
How about using single quotes for PHP and double quotes for SQL, that way you don't have to mess around with backslashes to escape quotes; using some whitespace also helps to make query better to read:
mysql_query(
'UPDATE personas SET
toolbar_id="' . $result . '"
WHERE
download_ff LIKE "%' . $result . '%" ' );
Did not debug about the divistion by zero error.
But your problem seems to be improper string formatting and concatenation,
PHP might be treating % as modulus operation with empty string ( i.e. 0 );
<?php
$a = 10;
$b = a%'';
?> /* would give : Warning: Division by zero on line 4 */
Try the second version of the query, it would work :
http://codepad.org/6erRjYa7
<?php
$result = "foo";
$query = $query = 'UPDATE personas SET toolbar_id=\'' . $result . '\' WHERE download_ff LIKE concat('%',\'' . $result . '\','%')';
echo $query;
$queryNew = "UPDATE personas SET toolbar_id='".$result."' WHERE download_ff LIKE concat('%','".$result."','%')";
echo PHP_EOL ;
echo $queryNew;
?>