This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 6 years ago.
I've looked around the internet and haven't been able to resolve this issue.
I'm trying to insert a row into a mySQL table using PDO through this function
function newItem($name, $desc, $price, $catID){
echo $name . "\n";
echo $price . "\n";
echo $desc . "\n";
echo $catID . "\n";
$conn = self::connect();
//INSERT Order
$sql = "INSERT INTO catalogue (Name, Price, CatID, Desc)
VALUES ('$name', $price, $catID, '$desc')";
// use exec() because no results are returned
$conn->exec($sql);
}
when i do, i get this error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 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 'Desc) VALUES ('User', 0.00, 3, 'theUser')' at line 1' in C:\xampp\htdocs\classes\catalogue.php:65 Stack trace: #0 C:\xampp\htdocs\classes\catalogue.php(65): PDO->exec('INSERT INTO cat...') #1 C:\xampp\htdocs\classes\main.php(39): Catalogue->newItem('User', 'theUser', '0.00', '3') #2 {main} thrown in C:\xampp\htdocs\classes\catalogue.php on line 65
I can confirm that the self::connect(); method works, and the problem only occurs when i try to insert data into the Desc column.
I've spent a good while trying to sort this issue, however my knowledge of PDO is quite vague....
Can anyone see where I've gone wrong?
the echo's show this:
User 0.00 theUser 3
DESC is a keyword. You have to escape the column Name using backtics or better rename the column.
$sql = "INSERT INTO catalogue (Name, Price, CatID, `Desc`)
VALUES ('$name', $price, $catID, '$desc')";
For more Information about keywords see the official documentation.
Desc is reserved keyword in mysql in must be in backtick https://dev.mysql.com/doc/refman/5.7/en/keywords.html.html and use prepare and bind statement
$sth = $conn->prepare("INSERT INTO catalogue (Name, Price, CatID, `Desc`)
VALUES (:Name, :Price, :CatID, :Desc)");
$sth->bindParam(':Name', $name, PDO::PARAM_STR);
$sth->bindParam(':Price', $price, PDO::PARAM_STR);
$sth->bindParam(':CatID', $catID, PDO::PARAM_INT);
$sth->bindParam(':Desc', $desc, PDO::PARAM_STR);
$sth->execute();
Try this
$sql = "INSERT INTO catalogue (Name, Price, CatID, Desc)
VALUES ('".$name."', $price, $catID, '".$desc."')";
Related
I have a function that does an INSERT:
function insertData($data){
global $dbh;
$sql = sprintf(
"INSERT INTO location " .
"(" .
"data1, " .
"data2, " .
"data3" .
") " .
"VALUES ('%s', '%s', '%s')",
$data['data1'],
$data['data2'],
$data['data3']
);
echo "$sql \n";
$adjusted = $dbh->quote($sql);
$stmt = $dbh->prepare($adjusted);
$stmt->execute();
$lastId = $dbh->lastInsertId();
return $lastId;
}
When the function is called, I get this error:
INSERT INTO location (data1, data2, data3) VALUES ('Blah1', 'Blah2', 'Blah3')
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 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 ''INSERT INTO location (data1, data2, data3) VALUES (\'Bl' at line 1' in /var/www/test/lib/saveData.php:59
Stack trace:
#0 /var/www/test/lib/saveData.php(59): PDO->prepare(''INSERT INTO lo...')
#1 /var/www/test/lib/saveData.php(10): insertData(Array)
If I run the insert directly it works fine.
I can't figure out what PDO does not like about my syntax.
UPDATE:
Is there a significant difference between using the paramaterization
$sql = "INSERT INTO location (data1, data2, data3) VALUES (?, ?, ?)";
or
$sql = "INSERT INTO location (data1, data2, data3) VALUES (:data1, :data2, :data3)";
UPDATE 2
function insertData($data){
global $dbh;
$sql = "INSERT INTO location " .
"(" .
"data1, " .
"data2, " .
"data3, " .
"data4" .
") VALUES (?, ?, ?, ?)";
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
$lastId = $dbh->lastInsertId();
return $lastId;
}
UPDATE 3 - A debrief For the sake of other readers
I was being clever with sprintf() based on an example I picked up somewhere.
Using sprintf() to build the sql statement is not the same as using named or anonymous bind parameters, so I used the '?' bind parameter and everything worked fine.
Also, I am stuck building on an old system for now, so the shorthand [] array notation was also interfering with successful completion of the task.
Thanks for the input to those who responded.
You are not preparing your statement correctly. sprtinf and quote are breaking your query. Get rid of them and pass the values to execute
function insertData($data) {
global $dbh;
$sql = 'INSERT INTO location
(
data1,
data2,
data3
) VALUES (:data1, :data2, :data3)';
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
'data1' => $data['data1'],
'data2' => $data['data2'],
'data3' => $data['data3']
));
$lastId = $dbh->lastInsertId();
return $lastId;
}
Update:
I have added named placeholders, but I am still building the array manually. If you are sure that $data contains exactly the number of items matching your placeholders you can pass it in directly to execute.
This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 4 years ago.
// Not working
$stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)".
" VALUES ($phone_1,$phone_2,$phone_3)");
$stmt->execute();
// Works
$stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)".
" VALUES (?,?,?)");
$stmt->execute([$phone_1, $phone_2, $phone_3]);
When the first one is executed, it prints the error:
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1
no such column: blablabla in
C:\Users\zahha\IdeaProjects\icd0007\index.php:78 Stack trace: #0
C:\Users\zahha\IdeaProjects\icd0007\index.php(78):
PDO->prepare('INSERT INTO peo...') #1 {main} thrown in
C:\Users\zahha\IdeaProjects\icd0007\index.php on line 78
The second one works perfectly. What is the problem? Just wondering.
You need quotes around the variables in the first one, to indicate that the values are string literals in SQL.
$stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)".
" VALUES ('$phone_1','$phone_2','$phone_3')");
To make the first one work, you should put the variables between '. For example:
$stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)".
" VALUES ('$phone_1','$phone_2','$phone_3')");
$stmt->execute();
Or taking them out of the string, like:
$stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)".
" VALUES ('".$phone_1."','".$phone_2."','".$phone_3."')");
$stmt->execute();
I'm trying to start a transaction is mysql and insert data into the database. The database source sql can be found on github here. Here is the error:
Error: START TRANSACTION; INSERT INTO Books(Title, PublicationDate,
PurchaseDate, Description, LocationID, GenreID) VALUES('Simple
Genius', '2008-4-1','2009-5-7','','Hardbook Library','Fiction'); SET
#bookid = LAST_INSERT_ID(); INSERT INTO BookAuthors(FirstName,
MiddleName, LastName) VALUES('David', '', 'Baldacci'); SET #authorid =
LAST_INSERT_ID(); INSERT INTO AuthorsInBooks(AuthorID, BookID)
VALUES(#authorid, #bookid); COMMIT; 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 'INSERT INTO Books(Title,
PublicationDate, PurchaseDate, Description, LocationID,' at line 3
Near 'INSERT INTO Books(Title, PublicationDate, PurchaseDate, Description, LocationID,' doesn't make sense to me because it is missing GenreID after LocationID. Am i missing something? When I copy and paste this code into phpmyadmin it works fine. My php version is 5.4.
Here is php code:
$sql = "
START TRANSACTION;
INSERT INTO Books(Title, PublicationDate, PurchaseDate, Description, LocationID, GenreID)
VALUES('".$Title."', '".$YearWritten."','".$YearPurchased."','".$Description."','".$Location."','".$Genre."');
SET #bookid = LAST_INSERT_ID();
INSERT INTO BookAuthors(FirstName, MiddleName, LastName)
VALUES('".$AuthFirstName."', '".$AuthMiddleName."', '".$AuthLastName."');
SET #authorid = LAST_INSERT_ID();
INSERT INTO AuthorsInBooks(AuthorID, BookID)
VALUES(#authorid, #bookid);
COMMIT;
";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
mysqli_query() can only execute 1 query, if you want to execute multiple queries, you need:
if (mysqli_multi_query($conn, $sql)) {
In response to your comment "Can I see an example of what you mean #eggyal ?":
// mysqli provides API calls for managing transactions
mysqli_autocommit($conn, false);
// parameterise variables - NEVER concatenate them into dynamic SQL
$insert_book = mysqli_prepare($conn, '
INSERT INTO Books
(Title, PublicationDate, PurchaseDate, Description, LocationID, GenreID)
VALUES
(?, ?, ?, ?, ?, ?)
');
// bind the variables that (will) hold the actual values
mysqli_stmt_bind_param(
$insert_book,
'siisss', // string, integer, integer, string, string, string
$Title, $YearWritten, $YearPurchased, $Description, $Location, $Genre
);
// execute the statement (you can change the values of some variables and
// execute repeatedly without repreparing, if so desired - much faster)
mysqli_stmt_execute($insert_book);
// mysqli provides API calls for obtaining generated ids of inserted records
$book_id = mysqli_insert_id($conn);
// ... etc ...
// use the API call to commit your transaction
mysqli_commit($conn);
// tidy up
mysqli_stmt_close($insert_book);
Note that I've not included above any error detection/handling, which you'd certainly want to include in any real-world code.
This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 8 years ago.
I have been staring at the below code for over an hour any cannot see any issues.
public function add($data){
$sql = 'INSERT INTO ' . $this->name . '(fbid, userAccessToken, name, location, story, gender, email, email_md5, referrer, date, use, optin) VALUES (:fbid, :userAccessToken, :name, :location, :story, :gender, :email, :email_md5, :referrer, :date, :use, :optin)';
$mysqldate = date('Y-m-d G:i:s');
$result = $this->dbh->prepare($sql);
if($result->execute(array(
':fbid' => $data['fbid'],
':userAccessToken' => $data['userAccessToken'],
':name' => $data['name'],
':location' => $data['location'],
':story' => $data['story'],
':gender' => $data['gender'],
':email' => $data['email'],
':email_md5' => md5($data['email']),
':referrer' => $data['referrer'],
':date' => $mysqldate,
':use' => $data['use'],
':optin' => $data['optin']
))){
$return = $this->dbh->lastInsertId();
}
}
The error is
PHP Warning: PDOStatement::execute() [pdostatement.execute]:
SQLSTATE[42000]: Syntax error or access violation: 1064 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 'use, optin)
VALUES ('517371547', 'no-auth', 'Shane Jones', 'Manchest' at line 1
USE is a reserved word in mySQL.
You need to put it in backticks, or use a different column name.
use is a keyword in MySQL. If you want to use it as a column identifier, enclose it in backticks:
$sql = 'INSERT INTO `' . $this->name . '` ( `fbid`, `userAccessToken`, `name`, `location`, `story`, `gender`, `email`, `email_md5`, `referrer`, `date`, `use`, `optin`) VALUES (:fbid, :userAccessToken, :name, :location, :story, :gender, :email, :email_md5, :referrer, :date, :use, :optin)';
Anyway you should always enclose all identifiers in backticks, to prevent such errors!
USE is a reserved keyword that must be enclosed with backticks ` (see documentation).
Your problem comes from the fact that you are building your query manually.
While with whatever sane database abstraction library which will take the duty of building syntactically correct queries for you, the code become as small as few short lines:
public function add($data){
global $db;
$data['date'] = date('Y-m-d G:i:s');
$db->query('INSERT INTO ?n SET ?u',$this->name,$data);
return $db->insertId();
}
and raise no error on any of nearly hundred reserved words even if you know none of them.
I'm repeatedly getting a syntax error when inserting in to mysql, normally this works fine but I can't seem to get it to work. I can echo out the variables no problem but for some reason I can't insert them.
variables (the session vars are brought over from another page)
session_start();
$name=$_SESSION['bName'];
$email=$_SESSION['email'];
$ship_address = $_SESSION['sAddress'];
$voucher=$_SESSION['voucher'];
$sku=$_SESSION['sku'];
$credit_card=$_POST['credit_card'];
$security_code=$_POST['security_code'];
$payment_type=$_POST['payment_type'];
$cc_number=substr($credit_card, 0, 4) . str_repeat('x', (strlen($credit_card) - 4)) . substr($credit_card, -4, 4);
$phone=$_SESSION['billPhone'];
$status="Redeemed";
$date = date('Y/m/d');
$tracking ="";
insert query
//Insert Queries
$sqlInsert = "INSERT INTO `customers`(`name`, `email`, `address`, `phone`, `sku`, `creditcard`, `securitycode`, `paymenttype`, `voucher`, `purchase_id`, `tracking`, `status`, `date_recieved`)
VALUES( $name, $email, $ship_address, $phone, $sku, $credit_card, $security_code, $payment_type, $voucher, $purchase_id, $tracking, $status, $date)";
mysql_query($sqlInsert) or die ('Error Inserting into database' . mysql_error());
I've also tried
VALUES( '$name', '$email', '$ship_address', '$phone', '$sku', '$credit_card', '$security_code', '$payment_type', '$voucher', '$purchase_id', '$tracking', '$status', '$date')
but it doesn't work. The error I get is
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 'lastname, fahad#semail.com, 22 toronto ont l6a0l4, 416-123-4567, 1001234, 1234567' at line 1
Any ideas?
Thanks
all string values must be quoted.
VALUES("'.$name.'", "'.$email.'" ...
Do it like this, so the fields are delimited:
VALUES( '$name', '$email', ...
check your error message to see what kind of garbage you are currently generating.
You could use PDO to create prepared statements instead. Then you won't have to worry about escaping your values like drdwilcox's example 'Jerry''s'. It also helps as a counter measure against SQL Injection attacks.
I would almost guarantee that you have a single-quote in your name field. If you want to place a single quote into a string field in SQL, you must double it: 'Jerry''s'
And you need the '$name' version.