Insert JSON decoded data into mysql with PDO - php

Database Structure:
Encoding into JSON:
I have some JSON encoded anime info stored on a text file using this code:
$info = array(
'mal_id' => $id,
'image' => $src,
'title' => $title,
'alt_title_eng' => $alt_eng,
'alt_title_syn' => $alt_syn,
'type' => $type,
'status' => $status,
'episodes' => $ep,
'genres' => $genres,
'rank' => $rank,
'synopsis' => $syno,
'modified' => date("Y-m-d H:i:s"),
'user' => 'system'
);
file_put_contents("scrap/anime-$id.txt", json_encode($info));
The contents of the text file is:
{"mal_id":18679,"image":"http:\/\/localhost\/images\/anime\/5\/54379.jpg","title":"Kill la Kill","alt_title_eng":" KILL la KILL","alt_title_syn":" KLK","type":" TV","status":" Currently Airing","episodes":25,"genres":"Action, Comedy, School","rank":421,"synopsis":"The story is set on a high school that the student council president Satsuki Kiryuuin rules by force....","user":"system"}
Decoding JSON and inserting into database
I'm trying to json_decode the contents and insert the values in mysql. The code I made without success is this:
$id= '18679';
$TABLE_PREFIX = 'exp_';
$dbh = new PDO('mysql:host='.$dbhost.';dbname='.$database.';charset=utf8', $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$JSON = json_decode(file_get_contents("scrap/anime-$id.txt"));
$stmt = $dbh->prepare("INSERT INTO {$TABLE_PREFIX}animedb
(mal_id, image, title, alt_title_eng, alt_title_syn, type, status, episodes, genres, rank, synopsis, modified, user)
values(:mal_id, :image, :title, :alt_title_eng, :alt_title_syn, :type, :status, :episodes, :genres, :rank, :synopsis, :modified, :user)
on duplicate key update title= :title, image= :image, alt_title_eng= :alt_title_eng, alt_title_syn= :alt_title_syn, status= :status, episodes= :episodes, genres= :genres, rank= :rank, synopsis= :synopsis, modified= :modified, user= :user");
$user = 'system';
$modified = 'NOW()';
$stmt->bindParam(':mal_id', $id);
$stmt->bindParam(':image', $JSON->image, PDO::PARAM_STR);
$stmt->bindParam(':title', $JSON->title, PDO::PARAM_STR);
$stmt->bindParam(':alt_title_eng', $JSON->alt_title_eng, PDO::PARAM_STR);
$stmt->bindParam(':alt_title_syn', $JSON->alt_title_syn, PDO::PARAM_STR);
$stmt->bindParam(':type', $JSON->type, PDO::PARAM_STR);
$stmt->bindParam(':status', $JSON->status, PDO::PARAM_STR);
$stmt->bindParam(':episodes', $JSON->episodes);
$stmt->bindParam(':genres', $JSON->genres, PDO::PARAM_STR);
$stmt->bindParam(':rank', $JSON->rank);
$stmt->bindParam(':synopsis', $JSON->synopsis, PDO::PARAM_STR);
$stmt->bindParam(':modified', $modified, PDO::PARAM_STR);
$stmt->bindParam(':user', $user, PDO::PARAM_STR);
$stmt->execute() ;
Problem:
Using try/catch, I'm only getting this error:
SQLSTATE[HY093]: Invalid parameter number
I've searched for solutions for this error message, but couldn't find the right solution for my problem.

Is your SQL query has been tested ? Otherwise, try
... on duplicate key update title= values(title), ...
instead of
... on duplicate key update title= :title, ...

Related

Error HY093 on executing INSERT into table

This is the table where I´m trying to the the insert.
When i try to make a insert using pdo I get the following error:
Array ( [0] => HY093 [1] => [2] => )
All of the information comes from a html form.
The connection to the db is working because before I do this insert I do a fetch so that's not the problem.
I already checked all the variables with echo and they are correct.
Also tried to add the column 'id' to the sql, and give it the value NULL, but the error is the same as the above.
But since the column 'id' is auto incremented i didn't put it in the sql. See my code above to understand what I did.
$nome = $_POST['name'];
$mail = $_POST['email'];
$psw = $_POST['pass'];
$ni = $_POST['nif'];
This two variables comes from a fetch, and it works. They are only here because the belong to the Insert statement.
$roleid = $row['id'];
$rolen = $row['nome'];
$sql = "INSERT INTO users ( nome, email, psw, nif, role_id, role_name)
VALUES ( :nome, :mail, :psw, :ni, :roleid, :rolen)";
$stmt = $db1->prepare($sql);
$stmt->bindValue('nome', $nome, PDO::PARAM_STR);
$stmt->bindValue('email', $mail, PDO::PARAM_STR);
$stmt->bindValue('psw', $psw, PDO::PARAM_STR);
$stmt->bindValue('nif', $ni, PDO::PARAM_INT);
$stmt->bindValue('role_id', $roleid, PDO::PARAM_INT);
$stmt->bindValue('role_name', $rolen, PDO::PARAM_STR);
$stmt->execute();
$error = $stmt->errorInfo();
print_r($error);
Executing this insert I get the following error:
Array ( [0] => HY093 [1] => [2] => )
This is the solution to the question, I wasn't using the same name in the bindValue() function
$name = $_POST['name'];
$email = $_POST['email'];
$psw = $_POST['psw'];
$nif = $_POST['nif'];
$roleid = $row['id'];
$rolen = $row['nome'];
$sql = "INSERT INTO users ( nome, email, psw, nif, role_id, role_name)
VALUES ( :name, :email, :psw, :nif, :roleid, :rolen)";
$stmt = $db1->prepare($sql);
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
$stmt->bindValue(':psw', $psw, PDO::PARAM_STR);
$stmt->bindValue(':nif', $nif, PDO::PARAM_INT);
$stmt->bindValue(':roleid', $roleid, PDO::PARAM_INT);
$stmt->bindValue(':rolen', $rolen, PDO::PARAM_STR);
$stmt->execute();

Insert and update same table with transactions

Since I can't/don't know how to auto_increment two columns in one table I trying to do this with transactions. This is what I trying
$pdo->beginTransaction();
try
{
$sql = "INSERT INTO users ( username, password, firstname, lastname, email, user_image, path)
VALUES (:username, :password, :firstname, :lastname, :email, :user_image, :path)";
$q = $pdo->prepare($sql);
$q->execute(array(
':username' => $username,
':password' => sha1($password),
':firstname' => $firstname,
':lastname' => $lastname,
':email' => $email,
':user_image' => $forDB,
':path' => $path,
));
$lastInsertID = $pdo->lastInsertId();
$sql = $pdo->prepare("INSERT INTO users (usertype)
VALUE (:user_id)");
$sql->execute(array(
':user_id' => $lastInsertID
));
$pdo->commit();
}
// any errors from the above database queries will be catched
catch (PDOException $e)
{
// roll back transaction
$pdo->rollback();
// log any errors to file
ExceptionErrorHandler($e);
exit;
}
So basically I want to insert in column usertype the ID of this record (user_id) both columns must be equal.
Now when I try with this .. it is save empty fields except for the usertype which is updated with lastInsertID
Change
$sql = $pdo->prepare("INSERT INTO users (usertype)
VALUE (:user_id)");
to this
$sql = $pdo->prepare("UPDATE users SET usertype=:user_id WHERE user_id=:user_id");

PHP PDO bindParam() and MySQL BIT

I'm trying to update data in a table with a BIT type value in it, like the following :
// $show_contact is either '1' or '0'
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
The problem is, it never changes the value, it remains '1' as set on PHPMyAdmin. I tried different PDO::PARAM_ types without success, everything else is working.
edit full script
$sql = "UPDATE users SET password = :password, address = :address, postal = :postal, city = :city, contact = :contact, show_contact = :scontact WHERE id = :id";
$query = $dbh->prepare($sql);
$query->bindValue(':id', $user->id, PDO::PARAM_INT);
$query->bindValue(':password', md5($password), PDO::PARAM_STR);
$query->bindValue(':address', $address, PDO::PARAM_STR);
$query->bindValue(':postal', $postal, PDO::PARAM_STR);
$query->bindValue(':city', $city, PDO::PARAM_STR);
$query->bindValue(':contact', $contact, PDO::PARAM_STR);
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
$query->execute();
PDO has a bit of a bug where any parameter passed to a query, even when specifically given as PDO::PARAM_INT is treated as a string and enclosed with quotes. READ THIS
The only way to tackle it is to try the following:
$show_contact = (int)$show_contact;
$query->bindValue(':scontact', $show_contact, PDO::PARAM_INT);
I believe that the BIT type is mapped to PDO's PARAM_BOOL. Try using it with strictly boolean input.
$show_contact = (bool) $show_contact; // '0' => FALSE, '1' => TRUE
$query->bindValue(':scontact', $show_contact, PDO::PARAM_BOOL);

INSERT INTO table VALUES - mysql_query to PDO

trying to insert values from an old mysql_query using the new PDO and can't seem to get it. Here's the old code that works with the old method:
$query = mysql_query("INSERT INTO videos VALUES ('','$title',time(),'0','$length','','$name','$cat','$reciter','$genre')");
I've tried variations of the following code taken from another question on stack, but nothing that works for me.
$query = "UPDATE people
SET price=?,
contact=?,
fname=?,
lname=?
WHERE id=? AND
username=?";
$stmt = $dbh->prepare($query);
$stmt->bindParam(1, $price);
$stmt->bindParam(2, $contact);
$stmt->bindParam(3, $fname);
$stmt->bindParam(4, $lname);
$stmt->bindParam(5, $id);
$stmt->bindParam(6, $username);
$stmt->execute();
the first value to be inserted is an auto increment value in the db. I am at a loss as to how to write that with the new PDO. Then the third is an attempt at a timestamp. All others are values that exist in the script already.
So this is more along the lines of what I'm looking for.. Its what I have now, but doesn't work.
$sql = "INSERT INTO videos (id, title, timestamp, views, length, image, vid_url, cetegory, reciter, genre)
VALUES (:id, :title, :timestamp, :views, :length, :image, :vid_url, :category, :reciter, :genre)";
$query = $DBH->prepare($sql);
$results = $query->execute(array(
":id" => '',
":title" => $title,
":timestamp" => time(),
":views" => '0',
":length" => $length,
":image" => '',
":vid_url" => $name,
":category" => $cat,
":reciter" => $reciter,
":genre" => $genre
));
If id is an autoincrement, don't pass it to your query. If you specify a value to be inserted to an autoincrement table, sql will attempt to insert that value. so don't include it in the query, let SQL do that.
Secondly, if the third field is a timestamp, set the default to
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
SQL will update the timestamp automatically on update or insert (if you only want it on insert just put CURRENT_TIMESTAMP. then you also can drop that row.
You can also drop the images row if you aren't inserting anything there either, no point to put something in the query if you're not using it!
Also, the key PDO looks for doesn't have the colon (:) so if your item is :title, the array key will be just 'title'. So, your code should look something like:
$sql = "INSERT INTO videos ( title, views, length,, vid_url, cetegory, reciter, genre)
VALUES (:title, :views, :length, :vid_url, :category, :reciter, :genre)";
$query = $DBH->prepare($sql);
$results = $query->execute(array(
"title" => $title,
"views" => '0',
"length" => $length,
"vid_url" => $name,
"category" => $cat,
"reciter" => $reciter,
"genre" => $genre
));

pdo statement failing to execute

i have a pdo block for inserting values into my table as follows
try{
$user = 'root';
$pass = null;
$pdo = new PDO('mysql:host=localhost; dbname=divebay', $user, $pass);
$name = $_POST['name'];
$desc = $_POST['description'];
$cond = $_POST['condGroup'];
$sprice = $_POST['sprice'];
$iprice = $_POST['iprice'];
$incprice = $_POST['incprice'];
$duration = $_POST['duration'];
$img = $_POST['img'];
$owner = $_SESSION['username'];
$valid = "set";
$stmt2 = $pdo->prepare("SELECT * FROM auction WHERE ID = :id");
$stmt2->bindParam(":id", $random, PDO::PARAM_INT);
while(isset($valid)){
$random = rand(100000,999999);
$stmt2->execute();
if(!$stmt2->fetch(PDO::FETCH_ASSOC)){
unset($valid);
}
}
$timestamp = time() + ($duration * 24 * 60 * 60);
$stmt = $pdo->prepare("INSERT INTO auction(ID, name, owner, holder, sprice, iprice, incprice, etime, img, condition, description)
VALUES (:id, :name, :owner, :holder, :sprice, :iprice, :incprice:, :etime, :img, :condition, :description");
$stmt->bindParam(':id', $random, PDO::PARAM_INT);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':owner', $owner, PDO::PARAM_STR);
$stmt->bindParam(':holder', $owner, PDO::PARAM_STR);
$stmt->bindParam(':iprice', $iprice, PDO::PARAM_STR);
$stmt->bindParam(':sprice', $sprice, PDO::PARAM_STR);
$stmt->bindParam(':incprice', $incprice, PDO::PARAM_STR);
$stmt->bindParam(':etime', $timestamp, PDO::PARAM_INT);
$stmt->bindParam(':img', $img, PDO::PARAM_STR);
$stmt->bindParam(':condition', $condition, PDO::PARAM_STR);
$stmt->bindParam(':description', $description, PDO::PARAM_STR);
if($stmt->execute()){
$worked ="yes";
}
}catch(PDOException $e){
echo $e->getMessage();
}
i cant tell why this statement wont execute, the $worked variable has not been set when it is the script is run. all database column names and datatypes have been checked correct as they are. ive never had a problem with a statement not executing until now. whats wrong? how do i go about debugging this?
If you setup the database connection with error mode exception PDO will throw an exception if something is wrong with your statement. I also see that you are using the MySQL driver for PDO. If you do this you should always disable emulated prepared statements. So I would write you connection as following (note that I have also set the encoding):
$pdo = new PDO('mysql:host=localhost; dbname=divebay;charset=utf8', $user, $pass);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Also see this post for more information about this.
Once you have done this you will see that your statement is wrong. You have one missing ) at the end of the statement:
$stmt = $pdo->prepare("INSERT INTO auction(ID, name, owner, holder, sprice, iprice, incprice, etime, img, condition, description)
VALUES (:id, :name, :owner, :holder, :sprice, :iprice, :incprice:, :etime, :img, :condition, :description)");
^
Modify this line:
$stmt = $pdo->prepare("INSERT INTO auction(ID, name, owner, holder, sprice, iprice, incprice, etime, img, condition, description)
VALUES (:id, :name, :owner, :holder, :sprice, :iprice, :incprice:, :etime, :img, :condition, :description");
To
$stmt = $pdo->prepare("INSERT INTO auction(ID, name, owner, holder, sprice, iprice, incprice, etime, img, condition, description)
VALUES (:id, :name, :owner, :holder, :sprice, :iprice, :incprice:, :etime, :img, :condition, :description)");
The difference is the ) at the end.
And tell me if it works now.

Categories