Error in MySQL update command. (in php) - php

Good Morning everyone,
I am using an update command in php to update data in mysql. This is my code:
$sql=mysql_query("UPDATE blpublication SET JournalName = '$_POST[journal]', AcceptanceDate = '$_POST[acceptancedate]', PublishedDate = '$_POST[publisheddate]', Comment = '$_POST[comment]'
WHERE JobNo = '$_POST[jobno]'");
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "record Updated";
It does updates the field but, it gives me the following error. And i can not figure it out why am i getting this error.
"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 '1' at line 1"
Can you help me in this
Best
Zeeshan

Can you tell us what the exactly output of $sql is? By the way, BIG security hole there. You should always escape query inputs namely:
$journal = mysql_real_escape_string($_POST['journal']);
$acceptance_date = mysql_real_escape_string($_POST['acceptancedate']);
$publish_date = mysql_real_escape_string($_POST['publisheddate']);
$comment = mysql_real_escape_string($_POST['comment']);
$job_no = intval($_POST['jobno']); // assuming jobNo is a number
$sql = <<<END
UPDATE blpublication
SET JournalName = '$journal',
AcceptanceDate = '$acceptance_date',
PublishedDate = '$publish_date',
Comment = '$comment'
WHERE JobNo = $jobno
END;
mysql_query($sql);
if (mysql_error()) {
die("Error executing query '$sql': " . mysql_error());
}
echo "record Updated";

I would sanitize your input first. This could lead to some very nasty errors such as what you are experincing and malicious attacks. Look up SQL Injection.

I think the problem is that you're running mysql_query twice. The first time it works and returns 1 (true), which you assign to $sql. Then you call mysql_query again, passing $sql (which equals 1). Of course "1" is not a valid SQL query, so you get the syntax error.
I wholeheartedly agree that you must sanitize those inputs!

Similar to the following post, i believe when you have any object or array syntax, you need to put in braces.
SET JournalName = '${_POST[journal]}'
edit: and yes, as others pointed out you are risking sql injection.

First of all, your code is prone to SQL injection, escape your POST values:
$journal = mysql_real_escape_string($_POST['journal']);
And to actually debug your query, we need the query itself. Add an echo() statement before the actual execution of the query and post the result, the POST values possibly contain some unexpected value.

Your general UPDATE syntax looks ok, except for the obvious injection possibilities, but you need to output $sql. One of your variables probably has a quote in it or some other issue like that....

Looking at the SQL UPDATE statement in your code, one thing leaps out at me. The table name is blpublication, are you maybe missing a 't', i.e. tblpublication?
Also you should really sanitise your input, otherwise you're going to be a victim of a SQL injection attack.

Try concatenating the $_POST values. Im not sure if including them without quoting the key is possible?
$sql= mysql_real_escape_string("UPDATE blpublication SET JournalName = '".$_POST['journal']."', AcceptanceDate = '".$_POST['acceptancedate']."', PublishedDate = '".$_POST['publisheddate']."', Comment = '".$_POST['comment']."'
WHERE JobNo = '".$_POST['jobno']."'");
$result = mysql_query($sql);
Note: mysql_* commands are depreciated. You should switch over to mysqli_*.

Related

Why is INSERT INTO followed by SELECT LAST_INSERT_ID() not outputting anything?

The PHP code I have inserts the HTML form data from the previous page into the database and in the same SQL statement return the PostID back from the inserted data. The PostID column is AUTO_INCREMENTING. I have been researching this problem for a week or two now and have found no significant solutions.
<?php
include("dbconnect.php");
mysql_select_db("astral_database", $con);
session_start();
$username = $_SESSION['username'];
$forumtext = $_POST["forumtext"];
$forumsubject = $_POST["forumsubject"];
$postquery = 'INSERT INTO Forums (Creator, Subject, Content) VALUES ("$username", "$forumsubject", "$forumtext"); SELECT LAST_INSERT_ID()';
$result = mysql_query($postquery, $con);
if (!$con) {
echo "<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (331: dbconnect experienced fatal errors while attempting to connect)";
die();
}
if ($username == null) {
echo "<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (332: Username was not specified while attempting to send request)";
die();
}
if ($result != null) {
echo "last id: " . $result;
$fhandle = fopen("recentposts.txt", "r+");
$contents = file_get_contents("recentposts.txt");
fwrite($fhandle, json_encode(array("postid" => $result, "creator" => $username, "subject" => $forumsubject, "activity" => time())) . "\n" . $contents);
fclose($fhandle);
mysql_close($con);
header("location: http://astraldevgroup.com/forums");
die();
} else {
die("<b>If you are seeing this, please send the information below to astraldevgroup#gmail.com</b><br>Error (330: Unhandled exception occured while posting forum to website.)<br>");
echo mysql_error();
}
mysql_close($con);
?>
First off, the mysql_query doesn't return anything from the SELECT statement. I haven't found anything that will properly run both the SELECT statement and the INSERT statement in the same query. If I try running them in two different statements, it still doesn't return anything. I tried running the following statement in the SQL console and it ran perfectly fine without errors.
INSERT INTO Forums (Creator, Subject, Content) VALUES ("Admin", "Test forum 15", "This is a forum that should give me the post id."); SELECT LAST_INSERT_ID();
The mysql_query function does not run multiple statements
Reference: http://php.net/manual/en/function.mysql-query.php
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server ...
That's one reason your call to mysql_query isn't returning a resultset.
The most obvious workaround is to not try to run the SELECT in the same query. You could use a call to the mysql_insert_id instead.
Reference: PHP: mysql_insert_id http://php.net/manual/en/function.mysql-insert-id.php
Answers to some of questions you didn't ask:
Yes, your example code is vulnerable to SQL Injection.
Yes, the mysql_ interface has been deprecated for a long time.
Yes, you should being using either PDO or mysqli interfaces instead of the deprecated mysql_ functions.
FOLLOWUP
Re-visiting my answer, looking again at the question, and the example code.
I previously indicated that the code was vulnerable to SQL Injection, because potentially unsafe values are included in the SQL text. And that's what it looked like on a quick review.
But looking at it again, that isn't strictly true, because variable substitution isn't really happening, because the string literal is enclosed in single quotes. Consider what the output from:
$foo = "bar";
echo '$foo';
echo '"$foo"';
Then consider what is assigned to $postquery by this line of code:
$postquery = 'INSERT ... VALUES ("$username", "$forumsubject", "$forumtext")';
Fixing that so that $username is considered to be a reference to a variable, rather than literal characters (to get the value assigned to $username variable incorporated into the SQL text) that would introduce the SQL Injection vulnerability.
Prepared statements with bind placeholders are really not that hard.
$result will never be null. It's either a result handle, or a boolean false. Since you're testing for the wrong value, you'll never see the false that mysql_query() returned to tell you that the query failed.
As others have pointed out, you can NOT issue multiple queries in a single query() call - it's a cheap basic defense against one form of SQL injection attacks in the PHP mysql driver. However, the rest of your code IS vulnerable other forms of injection attacks, so... better start reading: http://bobby-tables.com
Plus, on the logic side, why are you testing for a null username AFTER you try to insert that very same username into the DB? You should be testing/validating those values BEFORE you run the query.

How to solve parameters in MYSQLi?

I am having a problem in my php file named JO-dashboard.php. It displays the error presented below the code.
Here is my code:
<?php
$link = connectToDB();
$strXML = "<chart caption='Factory Output report' subCaption='By Quantity' pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units'>";
$strQuery = "select DISTINCT profile from vgprofile";
$result = mysqli_query($link, $strQuery) or die(mysqli_error());
if($result) {
while ($ors = mysqli_fetch_array($result)) {
$strQuery = "select sum(MT) as totalLM from tbljocreator where PROFILE =" . $ors['profile'];
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error());
$getresult2 = mysqli_fetch_array($result2);
$strXML .= "<set label='" . $ors['profile'] . "' value ='" . $getresult2['totalLM'] . "' />";
mysqli_free_result($result2);
}
}
mysqli_close($link);
$strXML .= "</chart>";
echo renderChart("FusionCharts/Column3D.swf", "", $strXML, "JoCreator", 450, 300, false, true);
?>
THE ERROR IS IN:
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error());
In the browser it shows:
Warning: mysqli_error() expects exactly 1 parameter, 0 given in C:\xampp\htdocs\LearningFusionCharts\MyFirstChart\JO-dashboard.php on line 29
the mysqli_error function requires a parameter. http://us3.php.net/mysqli_error
p.s clean up your code and using tabs :)
The initial problem
You have to pass the connection object to the function mysqli_error, like this:
$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));
And this...
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));
Note: your code must have another problem that will be revealed after you do this. PHP wouldn't be executing the part of mysqli_error if there weren't an error in the query or something related to it.
The hidden problem
In fact, I have reasons to think* the problem is that $ors['profile'] is string, and therefore it should be between quotation marks in the query string:
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . $ors['profile'] . '"';
*: This was confirmed in the comments. The error was:
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 'RIVETS' at line 1
In this case RIVETS is the value of $ors['profile'] and evidently it is an string, ergo it must go between quotation marks...but that doesn't mean it is safe.
SQL Injection
We could say that your code is correct, the same code will probably work is the data where different. Yet, since the values you are putting in the query string may not be entirely safe (even with the data comming from the database), you will have to escape the dangerous characters.
This is put in evidence by the error you got:
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 '"CUTTING DISC 4""' at line 1
In this case, the variable $ors['profile'] got the string CUTTING DISC 4". This value is comming from the database and is causes a problem. It contains 4" meaning four inches, but Mysql sees the quotation marks (") and thinks that that is the end of the string, and tries to interpret whatever comes after the quotation marks as SQL.
If this input weren't from the database, but form the user... it would be worst... a malicious user could take adventage of it to execute arbitrary commands in the database. The potential of this kind of attack is overwhelming.
I recommend the video Hacking Websites with SQL Injection - Computerphile, it is a very good introduction to SQL injection for those beginners to web security, database security or information security in general. To learn more about what can be potentially be done with this kind of attack, read SQL Injection Walkthrough (DVWA) by Trenton Ivey.
Preventing SQL Injection - The old way
The old way to solve this problem is to escape the characters. SQL allows to do so by using the backslash character (\). So, in this example you would have to pass 4\" instead of 4". But that is the tip of the iceberg, there are plenty of security problems with it.
Something you could do for ease of migration is to declare a function to sanitize the data you send to the database, the idea is to escape any possibly treating character... in fact there is a function for that in PHP (mysql_real_escape_string):
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . mysql_real_escape_string($ors['profile']) . '"';
The problems with the old way
But mysql_real_escape_string is deprecated and should not be used in new development (you would notice it is not form mysqli... ), this function has some quirks of itself too... for example there is no way to tell that function what character encoding you are using (it uses whatever the databases is using), and there has been reports of problems with it when using multibyte characters. That is the old way to solve this.
Here goes another recommendation: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets by Joel Spolsky. I understand if you don't want to read... get another video: Characters, Symbols and the Unicode Miracle - Computerphile
Preventing SQL Injection - The new and improved way
With that said, the correct solution is to migrate to prepared statements, they are not really that hard with mysqli, it would be something like this:
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = ?';
if($stmt = $link->prepare($strQuery))
{
//s for string
//i for integer
//d for double (or float)
$stmt->bind_param('s', $ors['profile']);
if (!$stmt->execute())
{
die mysqli_error($link);
}
}
else
{
die mysqli_error($link);
}
Read more about Prepared Statements at PHP.net.
Just change
mysqli_error()
to
mysqli_error($link)
in each of the places where it occurs.
ie 4th line:
$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));
and 8th line:
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));
Replace
mysqli_error()
by
mysqli_error($link)
By the way, if the error message is as clear, you don't need to ask here. Just read the manual.

Why do I get an SQL error when there is an apostrophe at the end of my URL?

Why do I get an error when I add ' to the end of a URL? For example : http://mywebsite.com/singel?id=24'
I get the following 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 '\' LIMIT 1' at line 1
This is shown everywhere if I put ' after any id in the query string.
What is wrong, and how it can be fixed?
Thank you.
You are inserting a non-escaped variable in an SQL query. And if this variable happens to contain SQL special chars, this can cause SQL syntax errors or worse.
You need to escape your variables before inserting them in your SQL queries.
Example:
$query = "SELECT * FROM users WHERE id = " . mysql_real_escape_string($id);
Instead of (this is WRONG, don't do this):
$query = "SELECT * FROM users WHERE id = $id LIMIT 1";
If $id is 24', the query becomes:
$query = "SELECT * FROM users WHERE id = 24' LIMIT 1";
As you can see, there is a ' after 24, which is a syntax error.
if a ' kills your query, you very obviously have an sql injection vulnerability. Read up on mysql_real_escape_string(), bobby-tables, and consider switching to PDO prepared statements.
Look here
http://www.codeproject.com/KB/database/SqlInjectionAttacks.aspx
You should learn something about SQL injection. Your Script is injectable now
This error usually means you are open to sql injections. This function is a bit more complicated than mysql_real_escape_string(), because it also does a PHP configuration test, to make sure you do not escape the data twice and to add Various PHP version support! (as per PHP Manual 1)
Just run this little nifty function on each of the submitted items, for inserts, updates or where statements:
function sql_injection($value){
$value = trim($value);
if(get_magic_quotes_gpc())
$value = stripslashes($value);
if(function_exists("mysql_real_escape_string")){
$value = mysql_real_escape_string($value);
}else
$value = addslashes($value);
return $value;
}
Ex:
$q = 'SELECT `blah` FROM `users` WHERE `id`='.sql_injection($_POST['id']);
This function does NOT replace server side validation, and everything should be validated before using it, always assume the worst :)

php mysql_query returns nothing after insert (and nothing is inserted either)

I've got the following code:
<?php
if(!empty($error_msg))
print("$error_msg");
else
{
require_once("../include/db.php");
$link = mysql_connect($host,$user,$pass);
if (!$link)
print('Could not connect: ' . mysql_error());
else
{
$sql = "insert into languages values(NULL,'$_POST[language]','$_POST[country_code]');";
$res = mysql_query($sql);
print("$sql<br>\n");
print_r("RES: $res");
mysql_close($link);
}
}
?>
In one word: it does not work. mysql_query doesn't return anything. If I try the same
query within php_myadmin, it works. It does not insert anything either. Also tried it as
user root, nothing either. Never had this before. Using mysql 5.1 and PHP 5.2.
Any ideas?
mysql_query will return a boolean for INSERT queries. If you var_dump $res you should see a boolean value being printed. It will return TRUE for a successful query, or FALSE on error. In no cases it ever returns NULL.
In addition, never pass input data (e.g.: $_POST) directly to an SQL query. This is a recipe for SQL injection. Use mysql_real_escape_string on it first:
$language = mysql_real_escape_string($_POST['language']);
$sql = "INSERT INTO language SET language='$language'";
And don't forget to quote your array indices (e.g.: $_POST['language'] instead of $_POST[language]) to prevent E_NOTICE errors.
You need to specify a database so the system knows which database to run the query on...
http://php.net/manual/en/function.mysql-select-db.php
Without selecting a database, your data will not be inserted
mysql_query returns a boolean for INSERT queries. If used in string context, such as echo "$res", true will be displayed as 1 and false as an empty string. A query error has possibly occured. Use mysql_error() to find out why the query has failed.
$sql = "insert into languages values(NULL,'$_POST[language]','$_POST[country_code]');";
This is very bad practise, as a malicious user can send crafted messages to your server (see SQL Injection).
You should at least escape the input. Assuming your column names are named 'language' and 'country_code', this is a better replacement for the above code:
$sql = sprintf('INSERT INTO LANGUAGES (language, country_code) VALUES ("%s","%s")',
mysql_real_escape_string($_POST['language']),
mysql_real_escape_string($_POST['country_code'])
);
For a description of the mysql_real_escape_string function, see the PHP Manual. For beginners and experienced programmers, this is still the best resource for getting information about PHP functions.
Instead of using $_POST directly, I suggest using the filter_input() function instead. It's available as of PHP 5.2.
With an INSERT query, mysql_query returns true or false according as the query succeeded or not. Here it is most likely returning false. Change the line print_r("RES: $res"); to print_r("RES: ".(int)$res); and most likely you will see it print RES: 0.
The problem may be that MySQL expects a list of column names before the VALUES keyword.
Also, you appear to be inserting POST variables directly into SQL - you should read up on SQL injection to see why this is a bad idea.
--I retract the quote comment, but still not good to directly insert $_POST values.--
Second, I don't think i've seen print_r quite used like that, try just using an echo.
And mysql_query is only expected a boolean back on an INSERT, what are you expecting?
Now ive got this:
$language = mysql_real_escape_string($_POST['language']);
$country_code = mysql_real_escape_string($_POST['country_code']);
$sql = "insert into shared_content.languages (id,language,country_code) values(NULL,$language,$country_code);";
$res = mysql_query($sql);
print("$sql<br>\n");
var_dump($res);
print(mysql_error());
mysql_close($link);
And the output:
insert into shared_content.languages (id,language,country_code) values(NULL,NETHERLANDS,NL);
bool(false) Unknown column 'NETHERLANDS' in 'field list'

Sending a slash through mysql

I'm not sure why this has stumped me. I have the following code
$website = "http://www.google.com";
$name = "Person";
if(!empty($website) {
$name = "[url=$website]$name[/url]";
}
Then i try to insert that into mysql. I tried adding mysql_real_escape_string to both $website and $name (after the if statement), thinking the "/url" might also cause problems.
$name = mysql_real_escape_string($name);
Still no luck though. Any advice? What am I missing? It's giving me this error
"Parse error: syntax error, unexpected '/', expecting T_STRING or T_VARIABLE or T_NUM_STRING"
try
if(!empty($website)) {
$name = "[url={$website}]{$name}[/url]";
}
then use,
mysql_real_escape_string ($name);
This is a PHP syntax problem.
The parser thinks $name[ is the start of a array reference you have to add curly bracelets to tell the parser where the variable name starts and end:
"[url={$website}]{$name}[/url]"
There wont be any problem at all. When reading from database you should then put stripslashes() around your value.
e.g.
$query = "SELECT field FROM table";
$row = mysql_fetch_array(mysql_query($query));
echo(stripslashes($row['field']));
And your output will be the same like YOUR input.
Make sure you're quoting values you send into a query, like so:
$sql = "INSERT INTO table (column) VALUES ('$value')";
Whatever is in $value gets passed into the query. If you leave out the quotes, bad things may happen even if you use mysql_real_escape_string(). Inside strings, forward slashes do not have any special meaning in MySQL, and so mysql_real_escape_string() leaves them intact. This is not a bug, but the documented, correct behaviour. Basically, you need to quote all values in your query.
However, the best solution IMHO is to use PDO and its parametrized queries instead of the mysql_XXX API. It's a bit more complicated (not much though), and it allows you to pass parameters into a query through an associative array, doing all the escaping and quoting you need for you.
Are you putting quotes around the value you want to insert? This will work
INSERT INTO table_name (column_name)
VALUES ('[url=$website]http://www.google.com[/url]')
This will fail
INSERT INTO table_name (column_name)
VALUES ([url=$website]http://www.google.com[/url])
So you might have in you php
$query = "INSERT INTO table_name (column_name) VALUES ('$name')";
// DO MYSQL_QUERY

Categories