I'm having a bit of trouble with a transaction query. I have 2 tables,
"subjects" and linking table call "tutorsubjects". I am using a MariaDB version 10.0.21. I have created the following query but I keep getting a "Syntax error or access violation: 1064" error.
public function addSubject($values){
try {
$temp = $this->db->query("
BEGIN;
INSERT INTO subjects
(subject_code, subject_name, subject_grade, subject_description, subject_category)
VALUES (:subject_code, :subject_name, :subject_grade, :subject_description, :subject_category);
SET #last_id = LAST_INSERT_ID();
INSERT INTO tutorsubject
(tutor_id , subject_id)
VALUES (:tutor_id, #last_id);
COMMIT;",$values);
return $temp;
} catch (DBException $e) {
echo "Error:<br/>" . $e->getMessage();
return null;
} catch (Exception $e) {
echo "Error:<br/>" . $e->getMessage();
return null;
}
}
The following is the values that are parsed through to the query
$array = array("subject_code" => $code,
"subject_name" => $subject_name,
"subject_grade" => $grade,
"subject_description" => $subject_description,
"subject_category" => $subject_category,
"tutor_id"=>$selecttutor);
I get the following error:
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 ''reach'.'subjects' ('subject_code', 'subject_name', 'subject_grade', 'subject_de' at line 1
Raw SQL : INSERT INTO 'reach'.'subjects' ('subject_code', 'subject_name', 'subject_grade', 'subject_description', 'subject_category') VALUES (:subject_code,:subject_name,:subject_grade,:subject_description,:subject_category);
My issue is that when I run this query in phpMyAdmin it completes without any issues. I am using a PDO MySQL class found here as the foundation for my DB interactions. I am starting to think that perhaps the class does not directly support transactions?
Any thoughts would be greatly appreciated.
Try having PHP do the work + using PDO transaction methods, values part not tested so you need to make sure its correct:
$this->db->beginTransaction();
$this->db->query("INSERT INTO subjects
(subject_code, subject_name, subject_grade, subject_description, subject_category)
VALUES (:subject_code, :subject_name, :subject_grade, :subject_description, :subject_category)", $values);
$values['last_id'] = $this->db->lastInsertId();
if (empty($values['last_id'])) {
$this->db->rollBack();
} else {
$this->db->query("INSERT INTO tutorsubject
(tutor_id , subject_id)
VALUES (:tutor_id, :last_id)", $values);
$this->db->commit();
}
You should try leaving the COMMIT and BEGIN queries alone.
Try:
// start the transaction
$this->db->query("BEGIN;");
//rest of your queries with db->query() go here
$this->db->query("INSERT INTO subjects
(subject_code, subject_name, subject_grade, subject_description, subject_category)
VALUES (:subject_code, :subject_name, :subject_grade, :subject_description, :subject_category);
SET #last_id = LAST_INSERT_ID();
INSERT INTO tutorsubject
(tutor_id , subject_id)
VALUES (:tutor_id, #last_id);");
//commit
$this->db->query("COMMIT;");
MySQL is trying to execute all these as one query and it doesn't recognise the whole command as separate queries. PhpMyadmin separates them on its own and that's why they run correctly there.
Something is adding apostrophes around database and table names. This is syntactically wrong (unless you have a certain ansi mode turned on). They need to be backtics (`).
Related
I have tried many solutions that I have found on stackoverflow but keep getting the same error when trying to update my tables within the one statement.
ERROR:
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 'WHERE docID=7' at line 2
Code:
<?php
if(isset($_POST['btn-revActivate']))
{
try
{
$database = new Database();
$db = $database->dbConnection();
$conn = $db;
$stmt=$conn->prepare("UPDATE tbl_revisions, tbl_documents SET revStatus='Active', docStatus='Draft'
WHERE revID=$rid AND docID=$docID ");
$stmt->bindparam("revStatus",$revStatus);
$stmt->bindparam(":id",$rid);
$stmt->bindparam("docStatus",$docStatus);
$stmt->bindparam(":docID",$docID);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
?>
Can someone please help as I don't know what is wrong with this statement.
Thanks.
You can't update multiple tables in one statement.if you want to update then you can use a transaction to make sure that two UPDATE statements are treated atomically.
BEGIN TRANSACTION;
UPDATE tbl_revisions
SET revStatus='Active', docStatus='Draft'
WHERE revID=$rid AND docID=$docID ';
UPDATE tbl_documents
SET revStatus='Active', docStatus='Draft'
WHERE revID=$rid AND docID=$docID ';
COMMIT;
for more information
https://dev.mysql.com/doc/refman/5.7/en/commit.html
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
Here is a snippet of my code:
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
$sth->execute($data);
print_r($this->pdo->errorInfo());
This should give me an error because the tables don't even exist. All I get however is this:
Array ( [0] => 00000 )
How can I get a better description of the error so I can debug the issue?
Try this instead:
print_r($sth->errorInfo());
Add this before your prepare:
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
This will change the PDO error reporting type and cause it to emit a warning whenever there is a PDO error. It should help you track it down, although your errorInfo should have bet set.
Old thread, but maybe my answer will help someone. I resolved by executing the query first, then setting an errors variable, then checking if that errors variable array is empty. see simplified example:
$field1 = 'foo';
$field2 = 'bar';
$insert_QUERY = $db->prepare("INSERT INTO table bogus(field1, field2) VALUES (:field1, :field2)");
$insert_QUERY->bindParam(':field1', $field1);
$insert_QUERY->bindParam(':field2', $field2);
$insert_QUERY->execute();
$databaseErrors = $insert_QUERY->errorInfo();
if( !empty($databaseErrors) ){
$errorInfo = print_r($databaseErrors, true); # true flag returns val rather than print
$errorLogMsg = "error info: $errorInfo"; # do what you wish with this var, write to log file etc...
/*
$errorLogMsg will return something like:
error info:
Array(
[0] => 42000
[1] => 1064
[2] => 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 'table bogus(field1, field2) VALUES ('bar', NULL)' at line 1
)
*/
} else {
# no SQL errors.
}
Maybe this post is too old but it may help as a suggestion for someone looking around on this :
Instead of using:
print_r($this->pdo->errorInfo());
Use PHP implode() function:
echo 'Error occurred:'.implode(":",$this->pdo->errorInfo());
This should print the error code, detailed error information etc. that you would usually get if you were using some SQL User interface.
Hope it helps
From the manual:
If the database server successfully
prepares the statement, PDO::prepare()
returns a PDOStatement object. If the
database server cannot successfully
prepare the statement, PDO::prepare()
returns FALSE or emits PDOException
(depending on error handling).
The prepare statement likely caused an error because the db would be unable to prepare the statement. Try testing for an error immediately after you prepare your query and before you execute it.
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
print_r($this->pdo->errorInfo());
I am having a syntax error with an sql statement I am executing but for the life of me I can't find any error.
I have created my own database class with functionality to make prepared statements and execute them, I don't think there is a problem with my implementation as I have never had any issues with it before now. But, just in case there is a problem there I am going to show the code for that too.
Prepare:
public function prepare($index, $sql) {
if(isset(self::$PS[$index])){
$ermsg = "Index [$index] is already in use.";
throw new Exception($ermsg, 1);
}
try{
self::$PS[$index] = $this->dbh->prepare($sql);
}
catch(PDOException $e){
return false;
}
return true;
}
and execute:
public function execute($index, Array $param = array()) {
if(!isset(self::$PS[$index])){
$ermsg = "Index [$index] is unavailable.";
throw new Exception($ermsg, 1);
}
foreach($param as $key => $val){
if(is_int($key)) ++$key;
$type = $this->getValueType($val);
$bnd = self::$PS[$index]->bindValue($key, $val, $type);
if(!$bnd){
$ermsg = "Paramater '$key' in [$index] failed to bind";
throw new Exception($ermsg, 2);
}
}
try{
$bnd = self::$PS[$index]->execute();
}
catch(PDOException $e){
$ermsg = "PDO-Error while executing prepared statement [$index] ".$e->getMessage();
throw new Exception($ermsg, 3);
}
if($bnd === false){
$ermsg = "Result error in prepared statement [$index]";
throw new Exception($ermsg, 3);
}
return self::$PS[$index];
}
As I mentioned, I have never experienced issues using this so I don't think it's the problem, but who knows.
Now my implementation:
$sql = "INSERT INTO ratings (course_id, overall, design, condition, service, value, rated_by, date_rated)
VALUES (:course_id, :overall, :design, :condition, :service, :value, :rated_by, now()))";
DBH::getInstance()->prepare('rateit', $sql);
$stmt = DBH::getInstance()->execute('rateit', array(
":course_id"=>$course_id,
":overall"=>$overall,
":design"=>$design,
":condition"=>$condition,
":service"=>$service,
":value"=>$value,
":rated_by"=>$log_user_id
));
}
if($stmt) {
echo 'suc, Thanks! Your ratings have been added to the course.';
exit();
}else{
echo 'err, There was an error rating the course. Please try again later';
exit();
}
This is the exact syntax error message I receive:
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 'condition, service, value, rated_by, date_rated) VALUES (1, 5, 5, 5, 5, 3, '18',' at line 1'
If someone can spot my syntax error, or maybe find something else wrong that would be causing this that would be awesome. Thanks for any help.
Condition is a reserved word in MySQL. That could be it.
According to 9.2 Schema Object Names, to use reserved words as identifiers they must be quoted. Use backticks or, with enabled ANSI_QUOTES SQL mode, double quotation marks. Quoting is not necessary if the reserved word follows a period in a qualified name.
$sql = "INSERT INTO ratings (course_id, overall, design, condition, service, value, rated_by, date_rated)
VALUES (:course_id, :overall, :design, :condition, :service, :value, :rated_by, now()))";
Should be:
$sql = "INSERT INTO ratings (course_id, overall, design, `condition`, service, value, rated_by, date_rated)
VALUES (:course_id, :overall, :design, :condition, :service, :value, :rated_by, now())";
Condition is a reserved word in MySQL. You should always use backticks ("`") in `table` and `column` names to avoid errors like that. Also looks like you have an extra ) at the end of the sql query
List of Reserved Words
First of all I'm new in web development so sorry if its a dumb question,I have an array, that the keys of the array are the id of the records that need to be updated in the database, i came with the bellow code to create the query and using mysql transaction to run the query (since few records should be updated together). the generated query works fine when i run it using command line, but with php code NO!
The code to generate the query :
$insert="";
if($run==true){
foreach($result as $key=>$x){
$insert = $insert ."update project set type='".$x."' "."where "."id=".$key.";";
}
//echo $insert;
$insert=$insert ."COMMIT;";
$insert= "START TRANSACTION;". $insert;
The result of the code:
START TRANSACTION;update project set type='project1' where id=1;update project set type='project2' where id=2;COMMIT;
The error that it gives me:
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 'update project set type='project1' where id=1;update project set type='project2'' at line 1
I did not include the sql connections and... since i believe in high percentage they are fine, but in case its necessary i can include them too.
Thanks in advance
Multiple queries are not supported using MySQL functions. You would need to break down the transaction:
$sql1 = UPDATE `project` SET `type`='project1' WHERE `id`=1;
$sql2 = UPDATE `project` SET `type`='project2' WHERE `id`=2;
You can however use mysqli_mutli_query or as mentioned in another answer PDO
You might want to switch to PDO which has an interface to transactions directly.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("update project set type= ? where id= ?");
$db->beginTransaction();
try {
foreach ($result as $key => $x) {
$db->execute(array($x, $key));
}
$db->commit();
} catch (PDOException $e) {
$db->rollBack();
throw $e;
}
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
Here is a snippet of my code:
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
$sth->execute($data);
print_r($this->pdo->errorInfo());
This should give me an error because the tables don't even exist. All I get however is this:
Array ( [0] => 00000 )
How can I get a better description of the error so I can debug the issue?
Try this instead:
print_r($sth->errorInfo());
Add this before your prepare:
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
This will change the PDO error reporting type and cause it to emit a warning whenever there is a PDO error. It should help you track it down, although your errorInfo should have bet set.
Old thread, but maybe my answer will help someone. I resolved by executing the query first, then setting an errors variable, then checking if that errors variable array is empty. see simplified example:
$field1 = 'foo';
$field2 = 'bar';
$insert_QUERY = $db->prepare("INSERT INTO table bogus(field1, field2) VALUES (:field1, :field2)");
$insert_QUERY->bindParam(':field1', $field1);
$insert_QUERY->bindParam(':field2', $field2);
$insert_QUERY->execute();
$databaseErrors = $insert_QUERY->errorInfo();
if( !empty($databaseErrors) ){
$errorInfo = print_r($databaseErrors, true); # true flag returns val rather than print
$errorLogMsg = "error info: $errorInfo"; # do what you wish with this var, write to log file etc...
/*
$errorLogMsg will return something like:
error info:
Array(
[0] => 42000
[1] => 1064
[2] => 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 'table bogus(field1, field2) VALUES ('bar', NULL)' at line 1
)
*/
} else {
# no SQL errors.
}
Maybe this post is too old but it may help as a suggestion for someone looking around on this :
Instead of using:
print_r($this->pdo->errorInfo());
Use PHP implode() function:
echo 'Error occurred:'.implode(":",$this->pdo->errorInfo());
This should print the error code, detailed error information etc. that you would usually get if you were using some SQL User interface.
Hope it helps
From the manual:
If the database server successfully
prepares the statement, PDO::prepare()
returns a PDOStatement object. If the
database server cannot successfully
prepare the statement, PDO::prepare()
returns FALSE or emits PDOException
(depending on error handling).
The prepare statement likely caused an error because the db would be unable to prepare the statement. Try testing for an error immediately after you prepare your query and before you execute it.
$qry = '
INSERT INTO non-existant-table (id, score)
SELECT id, 40
FROM another-non-existant-table
WHERE description LIKE "%:search_string%"
AND available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40
';
$sth = $this->pdo->prepare($qry);
print_r($this->pdo->errorInfo());