The following is throwing a syntax error. The entire query works in a MySQL client with literals, but breaks down when passing from PHP. In PHP, each query works if submitted separately, but not if within START and COMMIT.
The error:
1064: You have an error in your SQL syntax; check the manual ...etc...right
syntax to use near 'INSERT INTO user_degrees (user_id, degree_id, acadcat_id
, inst_id) VALUES (' at line 2
Query:
$query="START TRANSACTION;
INSERT INTO user_degrees (user_id, degree_id, acadcat_id, inst_id)
VALUES ((SELECT id FROM users WHERE users.username = '$user')
, '$degreeid', '$studyfocus', '$institution');
UPDATE users
SET degree".$dnum." = (SELECT LAST_INSERT_ID())
WHERE username = '$user';
COMMIT;";
All the $vars are class properties and pass integers, except for $user, which passes a username session variable. $dnum is used to change column names between instances of the class and I might be concatenating it incorrectly within MySQL.
PHP's mysql driver only allows a single query per mysql_query() call as a security measure. You'll have to issue multiple separate queries:
$result = mysql_query("START TRANSACTION");
$result = mysql_query("INSERT ...");
$result = mysql_query("UPDATE ...");
$result = mysql_query("COMMIT;");
... with appropriate checking at each stage to make sure the query didn't fail (which I've omitted from here).
Note that this security measure only applies to top-level queries. One one top-level query per call. You can have as many subqueries as you want/need.
Related
I am trying to use PHP to run consecutive MYSQL statements as shown in the code snippet below (which just copies one row to another and renames the id via a tmp table).
I am getting a repeated syntax error message. I've tried numerous iterations. And the code looks like code I've researched in the PHP Manual and other myql questions on SO (which do not include the php dimension).
Can anyone shine a light on why my php syntax is incorrect?
include("databaseconnect.php");// This obviously works. Used a zillion time
$sql ="CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id
= 1;";
$sql.="UPDATE tmp SET id=100 WHERE id = 1;";
$sql.="INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100;";
if ($conn->query($sql) === TRUE)
{
echo "Table row copied successfully. Do something with it";
}
else
{
echo "Error creating table: " . $conn->error;
//close connection etc
}
PHP Message back:
Error creating table: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UPDATE tmp SET id=100 WHERE id = 1INSERT INTO event_categoriesBU SELECT * FROM t' at line 1
Don't run a bunch of queries at once. Usually the success of one depends on all the other operations having been performed correctly, so you can't just bulldozer along as if nothing's gone wrong when there's a problem.
You can do it like this:
$queries = [
"CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id = 1",
"UPDATE tmp SET id=100 WHERE id = 1",
"INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100"
];
foreach ($query as $query) {
$stmt = $conn->prepare($query);
$stmt->execute();
}
Don't forget to enable exceptions so that any query failures will stop your process instead of the thing running out of control.
The reason you don't use multi_query is because that function does not support placeholder values. Should you need to introduce user data of some kind in this query you need to use bind_param in order to do it safely. Without placeholder values you're exposed to SQL injection bugs, and a single one of those is enough to make your entire application vulnerable.
It's worth noting that PDO is a lot more flexible and adaptable than mysqli so if you're not too heavily invested in mysqli, it's worth considering a switch.
You can't execute more than one SQL statement with query($sql), you must use multi_query($sql). Your script will then become something like this:
if ($conn->multi_query($sql) === TRUE)
{
echo "Table row copied successfully. Do something with it";
}
See the documentation for a complete example.
However, note that, as other users have well explained in the comments, executing multiple queries at the same time with this method can be potentially dangerous and should be avoided when possible, especially when handling user inputs.
You have better control of the execution flow if you execute one query at a time and check its result, rather than grouping all of them in a single call.
I am trying to use PHP to run consecutive MYSQL statements as shown in the code snippet below (which just copies one row to another and renames the id via a tmp table).
I am getting a repeated syntax error message. I've tried numerous iterations. And the code looks like code I've researched in the PHP Manual and other myql questions on SO (which do not include the php dimension).
Can anyone shine a light on why my php syntax is incorrect?
include("databaseconnect.php");// This obviously works. Used a zillion time
$sql ="CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id
= 1;";
$sql.="UPDATE tmp SET id=100 WHERE id = 1;";
$sql.="INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100;";
if ($conn->query($sql) === TRUE)
{
echo "Table row copied successfully. Do something with it";
}
else
{
echo "Error creating table: " . $conn->error;
//close connection etc
}
PHP Message back:
Error creating table: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UPDATE tmp SET id=100 WHERE id = 1INSERT INTO event_categoriesBU SELECT * FROM t' at line 1
Don't run a bunch of queries at once. Usually the success of one depends on all the other operations having been performed correctly, so you can't just bulldozer along as if nothing's gone wrong when there's a problem.
You can do it like this:
$queries = [
"CREATE TEMPORARY TABLE tmp SELECT * FROM event_categoriesBU WHERE id = 1",
"UPDATE tmp SET id=100 WHERE id = 1",
"INSERT INTO event_categoriesBU SELECT * FROM tmp WHERE id = 100"
];
foreach ($query as $query) {
$stmt = $conn->prepare($query);
$stmt->execute();
}
Don't forget to enable exceptions so that any query failures will stop your process instead of the thing running out of control.
The reason you don't use multi_query is because that function does not support placeholder values. Should you need to introduce user data of some kind in this query you need to use bind_param in order to do it safely. Without placeholder values you're exposed to SQL injection bugs, and a single one of those is enough to make your entire application vulnerable.
It's worth noting that PDO is a lot more flexible and adaptable than mysqli so if you're not too heavily invested in mysqli, it's worth considering a switch.
You can't execute more than one SQL statement with query($sql), you must use multi_query($sql). Your script will then become something like this:
if ($conn->multi_query($sql) === TRUE)
{
echo "Table row copied successfully. Do something with it";
}
See the documentation for a complete example.
However, note that, as other users have well explained in the comments, executing multiple queries at the same time with this method can be potentially dangerous and should be avoided when possible, especially when handling user inputs.
You have better control of the execution flow if you execute one query at a time and check its result, rather than grouping all of them in a single call.
I have a necessity to insert some record from one table1 in database1 to another table2 in database2.
So far I have this..
$records_r = mysqli_fetch_assoc(mysqli_query($conn_r, "SELECT * FROM `export` WHERE ID < 100"));
$columns_r = implode(",",array_keys($records_r));
$values_r = implode(",",array_values($records_r));
$import = mysqli_query($conn_i,"INSERT INTO NOTimport ($columns_r) values ($values_r)");
if (!$import) {
printf("Error: %s\n", mysqli_error($conn_i));
exit();}
It gives me the error:
Error: You have an error in your SQL syntax;
This is how the syntax looks:
INSERT INTO `NOTimport` ('xx,xx,xx,xx,xx,xx,xx,xx') values ('11,'11,E,2079,1931,xx,xx,x')
I am 99% sure that single quotes are causing the error, but why are there?
As per your original post https://stackoverflow.com/revisions/31116693/1 and completely overwriting your original post without marking it as an edit:
You're using the MySQL import reserved word
https://dev.mysql.com/doc/refman/5.5/en/keywords.html
It needs to be wrapped in ticks
INSERT INTO `import` ($columns_r) values ($values_r)
or rename that table to something other than a reserved word.
Plus, $values_r may require to be quoted and depending on what's being passed through $columns_r, you may need to use ticks around that.
I.e.:
INSERT INTO `import` (`$columns_r`) values ('".$values_r."')
Even then, that is open to SQL injection.
So, as per your edit with these values values ('11,'11,E,2079,1931,xx,xx,x'), just quote the values since you have some strings in there. MySQL will differentiate between those values.
Escape your values:
$values_r = implode(",",array_values($records_r));
$values_r = mysqli_real_escape_string($conn_r, $values_r);
or $conn_i I'm getting confused as to which variable is which here. Be consistent if you're using the same db.
Edit:
As stated in comments by chris85, use prepared statements and be done with it.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
http://php.net/pdo.prepared-statements
import is a reserved word in MYSQL. So, you need to use backticks (``) around it in your query.
So rewrite as follows:
$import = mysqli_query($conn_i,"INSERT INTO `import` ($columns_r) values ($values_r)");
Without Using PHP you can use MySql Query Which Will Perform Insert Operation As:-
$columns_r='`name`,`class`';
mysqli_query($conn_i,"INSERT INTO `import` ({$columns_r}) select {$columns_r} from `export`");
$sql="SELECT retail_peak, number from callplandata ";
$rs=mysql_query($sql,$conn);
$sql2='';
while($result=mysql_fetch_array($rs)) {
$sql2.="UPDATE callplandata set ".$_POST["callplancopy_newname"]." = '".$result[$_POST["callplancopy"]]."' where number = '".$result["number"]."'; ";
}
$rs2=mysql_query($sql2,$conn) or die(mysql_error());
I am trying to run the above queries, i have set $sql2 with a ; on the end so i just run one query rather than many separate queries.
I am getting this Error message:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UPDATE callplandata set dcabr = '0' where number = '44*116'; UPDATE callplandata' at line 1
when i echo $sql2, it looks like - http://www.wepaste.com/sql2/
mysql is deprecated but it also doesn't allow multiple statements in a single query.
You can however use multiple statements in a single query with mysqli by using mysqli_multi_query
Your immediate problem is that you are concatenating the $sql2 queries in the while loop to make one long string and then trying to execute the long string as one query.
You should move the execution of $sql2 into the while loop and drop the .= operator in favor of =:
$sql2=''; // Don't need this line
while($result=mysql_fetch_array($rs)) {
$sql2="
UPDATE callplandata
SET ".$_POST["callplancopy_newname"]."='".$result[$_POST["callplancopy"]]."'
WHERE number = '".$result["number"]."'
";
$rs2=mysql_query($sql2,$conn) or die(mysql_error());
}
You could also follow Rob's suggestion and execute the long string as a multiple query.
You would also do well to heed the warnings in the comments about SQL injection and deprecated functions.
You can actually run this as one statement by dropping the WHERE clause.. it is the same logic.
You are using an anti-pattern for what this code is trying to achieve: to update all rows in the callplancopy table (where the number column is not null) to set a column equal to a value.
(NOTE: the "WHERE number =" in the original UPDATE statement would effectively prevent rows with a NULL value in that column from being updated.)
The entire mess of code is performing RBAR (Row By Agonizing Row) what could be more simply and efficiently accomplished with just one single UPDATE statement issued to the database:
UPDATE callplandata d
SET d.`somecol` = 'someval'
WHERE d.number IS NOT NULL
(NOTE: The WHERE clause is included to reproduce the behavior of the original UPDATE statements, avoiding updating rows where the number column is NULL. If that's not desired, or is not necessary, then the WHERE clause can be omitted.)
(NOTE: This assumes that you are assigning a literal value to the column, as in the original UPDATE, where we see "callplancopy" enclosed in single quotes, making it a string literal. If you are meaning to copy the value from another column in the row, then we'd enclose the column identifier in backticks, not single quotes.)
SET d.`somecol` = d.`some_other_col`
If we insist on using the deprecated mysql interface, we really need use the mysql_real_escape_string function to make unsafe values "safe" for inclusion in the SQL text.
$sql = "UPDATE callplandata d
SET d.`" . mysql_real_escape_string($_POST["callplancopy_newname"]) . "`"
. " = d.`" . mysql_real_escape_string($_POST["callplancopy"] . "`
WHERE d.number IS NOT NULL";
# for debugging, echo out the SQL text
#echo $sql;
NOTE: The PHP mysql interface is deprecated. New development should make use of the PDO or mysqli interface.
I'm having problems with an INSERT statement, and the error only says:
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 '' at line 1
It's not helpful at all.
The version I have tried so far and failed is:
mysql_query("INSET INTO `cos` VALUES ('".$_GET['prod']."','".$_GET['page']."')");
[needless to say that the two variables when printed show the right values]
I've also tried versions with nothing around the table name, with ` or ', a million combinations really and nothing works. Not even with constants or into different tables. It just won't insert anything ever. I've checked the privileges (I'm logging into it with root), and it's all on.
I've tried similar stuff on two different machines with the same server (XAMPP 1.7.7) and it works. I'm completely baffled! What can it be?
Thank you for your time!
First and foremost, just type INSERT correctly.
Using _GET like that really opens you up to SQL INJECTIONS...
Do take a look into MySQL prepared statements.
It is also considered good practice to name the columns that you're inserting data into. That allows you to, latter on, insert extra-columns and keep application logic.
INSERT INTO cos(rowName1, rowName2) VALUES(?, ?)
Where ? would be prepared statements.
Correct:
mysql_query("INSERT INTO `cos` VALUES ('".$_GET['prod']."','".$_GET['page']."')");
Have you tried passing the $link to mysql_query ?
Like:
mysql_query("INSERT INTO `cos` VALUES ('".$_GET['prod']."','".$_GET['page']."')", $link);
EDIT:
And of course you must take some security measures before inserting anything into the database, maybe mysql_real_escape_string() or even prepared statements.
You are doing it wrong. Why aren't you escaping the values?
Php.net documentation is providing some good and safe working examples:
$query = sprintf("SELECT firstname, lastname, address, age FROM friends
WHERE firstname='%s' AND lastname='%s'",
mysql_real_escape_string($firstname),
mysql_real_escape_string($lastname));
// Perform Query
$result = mysql_query($query);
So adapted to your code:
$query = sprintf("INSERT INTO `cos` VALUES (%s, %s);",
mysql_real_escape_string($_GET['prod']),
mysql_real_escape_string($_GET['page']));
$result = mysql_query($query);
Please, always escape your values. And use INSERT, not INSET :)
first this is you are using INSET make it correct with INSERT like
$pro = mysql_real_escape_string($_GET['prod']);
$page = mysql_real_escape_string($_GET['page']);
mysql_query("INSERT INTO `cos` (column1, column2)
VALUES ('$pro', '$page')" );
you forget to set the column names...
Try this:
$prod = $_GET['prod'];
$page = $_GET['page'];
mysql_insert("INSERT INTO 'cos' VALUES('$prod','$page)");
This should very well do it :)