INSERT INTO doesn't fill all rows - php

I have a problem with my code, it is PayPal express Integration. I mean in its original state after some tweaking to match my database and so on it works, it fills rows with ex. payerID and so on.
I have in my database 2 tables - first is Products it has 5 Rows, like productID, Price, currency and so on, but I need 1 extra row - let's say we call it Credits. I manually added it to my database, filled Table Products with data.
Then I have another table called Orders- where I added Row called Credits too, than after successful payment+checkout matched Credits to chosen Product it should fill this Row Credits in Orders table. The problem that I have it that Order Table is filled with all data except that last Row -> Credits it's always showing NULL in the database.
This is part of my code:
public function getAllProducts()
{
$db = getDB();
$stmt = $db->prepare("SELECT * FROM products");
$stmt->bindParam("pid", $pid, PDO::PARAM_INT) ;
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
$db=null;
return $data;
}
public function getProduct($pid)
{
$db = getDB();
$stmt = $db->prepare("SELECT * FROM products WHERE pid=:pid");
$stmt->bindParam("pid", $pid, PDO::PARAM_INT) ;
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_OBJ);
$db=null;
return $data;
}
and this where I have a problem
public function orders()
{
$id = $_SESSION['session_id'];
$db = getDB();
$stmt = $db->prepare("SELECT P.product, P.price, P.product_img, P.currency, P.credits, O.created, O.oid FROM orders O, products P WHERE O.id_fk=:id AND P.pid = O.pid_fk ORDER BY O.created DESC");
$stmt->bindParam("id", $id, PDO::PARAM_INT) ;
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
$db=null;
return $data;
}
public function updateOrder($pid, $payerID, $paymentID, $token, $credits)
{
$id = $_SESSION['session_id'];
if($this->pyamentCheck($paymentID) < 1 && $id > 0){
$db = getDB();
$stmt = $db->prepare("INSERT INTO orders (id_fk, pid_fk, payerID, paymentID, token, created, credits) VALUES (:id, :pid, :payerID, :paymentID, :token, :created, :credits)");
$stmt->bindParam("paymentID", $paymentID, PDO::PARAM_STR) ;
$stmt->bindParam("payerID", $payerID, PDO::PARAM_STR) ;
$stmt->bindParam("token", $token, PDO::PARAM_STR) ;
$stmt->bindParam("pid", $pid, PDO::PARAM_INT) ;
$stmt->bindParam("id", $id, PDO::PARAM_INT) ;
$created = time();
$stmt->bindParam("created", $created, PDO::PARAM_INT) ;
$stmt->bindParam(":credits", $credits, PDO::PARAM_INT) ;
$stmt->execute();
$db=null;
return true;
}
else{
return false;
}
}
I can´t figure it out.

This is quite a frequent question so it deserves an answer, however obvious it may seem.
Once you have a working INSERT query and one of columns turns to be NULL, it means that the source variable contained NULL.
So the problem is neither with PDO, nor prepared statements, nor a database but simply with your source variable, $credits. You have to check your code related to this variable and make sure it does contain the desired value.

Related

How can I select all rows that meet specified criteria in two columns in sql

I have a table of orders containing order's info. Every order has a writer associated with it and a writer can be associated with multiple orders. Now every writer has an account where they need to login and see only orders associated with them. An order status can be in progress, completed or cancelled. In the writer's account they need to see orders in progress, cancelled and completed in separate tables. Now I wrote this sql query to fetch orders in order to fill in the "in progress" writer's table but dumping the result of the query return an array(0) { } meaning there no data fetched despite the fact that there two records in the orders table that matches the query's conditions. Can anyone please help me find out the problem with my query or the code in general? Thanks
// OrdersModel class
class OrdersModel{
static public function mdlShowWriterOrders($table, $item, $item1, $value, $value1){
$stmt = Connection::connect() -> prepare("SELECT * FROM $table WHERE $item = :$item AND $item1 = :$item1");
$stmt -> bindParam(":".$item, $value, PDO::PARAM_STR);
$stmt -> bindParam(":".$item1, $value1, PDO::PARAM_STR);
$stmt -> execute();
return $stmt -> fetchAll();
}
}
//ControllerCustomers class
class ControllerCustomers{
static public function ctrShowWriterOrders($item, $value, $item1, $value1){
$table = "orders";
$answer = OrdersModel::mdlShowWriterOrders($table, $item, $value, $item1, $value1);
return $answer;
}
}
// Calling ctrShowWriterOrders() function where required
$item = "writerId"; //column name in orders table
$value = $_SESSION["id"]; // session for currently logged in writer
$item1 = "status"; // status column in orders table
$value1 = 1; // 1 represents orders "in progress"
$orders = ControllerCustomers::ctrShowWriterOrders($item, $value, $item1, $value1);
var_dump($orders); // output: array(0) { }

Unable to insert into MySQL database with php

In this Insert function where I have to insert a book into the database. The author is already existed in the database and I am trying insert a book that is written by the same author. What I am trying to achieve is to prevent user from entering the already existing author that would make duplicate data. When I get to the record the changelog with BookID but I get the a MySQL error where it says
"PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'SELECT BookID from book WHERE BookID = 102' for column 'BookID' at row 1 in C:\wamp64\www\bookprojectdb\Model\bookInsertFunction.php on line 97".
function addBook2($existauthor, $bt, $ot, $yop, $genre, $sold, $lan, $cip, $bp, $ps, $userID){
global $conn;
try {
$conn->beginTransaction();
//Author Data already exist
//Book Data
$stmt = $conn->prepare("INSERT INTO book(BookTitle, OriginalTitle, YearofPublication, Genre,
MillionsSold, LanguageWritten, CoverImagePath, AuthorID)
VALUES(:bt, :ot, :yop, :genre, :sold, :lan, :cip, :authorid);");
$stmt->bindValue(':bt', $bt);
$stmt->bindValue(':ot', $ot);
$stmt->bindValue(':yop', $yop);
$stmt->bindValue(':genre', $genre);
$stmt->bindValue(':sold', $sold);
$stmt->bindValue(':lan', $lan);
$stmt->bindValue(':cip', $cip);
$stmt->bindValue(':authorid',$existauthor);
$stmt->execute();
//BookPlot Data
$lastbookID = $conn->lastInsertID();
$stmt = $conn->prepare("INSERT INTO bookplot(Plot, PlotSource, BookID)
VALUES(:bp, :ps, :bookid);");
$stmt->bindValue(':bp', $bp);
$stmt->bindValue(':ps', $ps);
$stmt->bindValue(':bookid', $lastbookID);
$stmt->execute();
//Changelog Date Create Insert. This inserts date created, bookid and userid.
$datecreated = (date('y-m-d h:m:s'));
$bookID = "SELECT BookID from book WHERE BookID = $lastbookID";
$stmt = $conn->prepare("INSERT INTO changelog(DateCreated, BookID, UserID)
VALUES(:datecreated, :bookid, :userid);");
$stmt->bindValue(':datecreated', $datecreated);
$stmt->bindValue(':bookid', $bookID);
$stmt->bindValue(':userid', $userID);
$stmt->execute();
//commit
$conn->commit();
}
catch(PDOException $ex) {
$conn->rollBack();
throw $ex;
}
}
$existauthor
$query = $conn->prepare("SELECT Name, Surname, AuthorID FROM author WHERE Name = :name AND Surname = :surname");
$query->bindValue(':name', $name);
$query->bindValue(':surname', $surname);
$query->execute();
$row = $query->fetch();
if($query->rowCount() < 1){ //if author doesn't exists
addBook($name, $surname, $nationality, $yob, $yod,
$bt, $ot, $yop, $genre, $sold, $lan, $cip, $bp, $ps, $userID);
header('location:../View/Pages/adminView.php');
}else {
//if author exists
$existauthor = $row['AuthorID'];
addBook2($existauthor,$bt, $ot, $yop, $genre, $sold, $lan, $cip, $bp, $ps, $userID);
header('location:../View/Pages/adminView.php');
}
I thought that by using "lastinsertID();", it would have recorded ID of recently created book. Please Help !
'SELECT BookID from book WHERE BookID = 102' - that is an incorrect integer value indeed.
You have this value assigned to a variable:
$bookID = "SELECT BookID from book WHERE BookID = $lastbookID";
and then you're trying to bind it in place of an integer:
$stmt->bindValue(':bookid', $bookID);
Here's the help you need:
if(!$stmt->execute()) echo $stmt->error;
You ALWAYS should expect errors, and have a workaround, but first you need to check for errors

Items in an SQL table with PDO query

I have an SQL table for a gallery, it has rows for id, userid, imagename.
I'm trying to write a function that calculates how many images a certain user has added, I'm new to PDO and SQL. This is what I have for my function;
// Photo Count
public function photoCount($id){
$this->db->query('SELECT * FROM gallery WHERE id = :id');
// Bind value
$this->db->bind(':id', $id);
$row = $this->db->single();
// Check row
$count = $this->db->rowCount();
return $count;
}
Do I need the line $row = $this->db->single(); or can I just return the rowCount at the moment all is being returned is 0's which is incorrect.
Any help appreciated.
Use SQL count function. If $this->db is a PDO object then...
public function photoCount($id){
$statement = $this->db->prepare('SELECT count(*) as c FROM gallery WHERE id = :id');
$statement->bindParam(":id", $id);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_OBJ);
return $result->c;
}

Named parameter in update where clause (pdo object)

I try to translate this query to my PDO object from this thread:
UPDATE table_name
SET col1 = <<new value>>,
col2 = <<new values>>,
last_modified_timestamp = <<new timestamp>>
WHERE primary_key = <<key column>>
AND last_modified_timestamp = <<last modified timestamp you originally queried>>
So i have a "modified" field in the mysql table and fetch the data (SELECT modified AS last_modified) to pre-fill in a hidden field in my form and post the value to the object:
$position->readOne();
$position->last_modified = $_POST['last_modified'];
<input name='last_modified' value='{$position->last_modified}'>
My object update query looks like:
UPDATE positions
SET
... some values ...
WHERE id=:id
AND modified=:last_modified
$stmt->bindParam(":last_modified", $this->last_modified);
If I check the posted variables, everything looks fine but the update query ignores my second where clause completely and override the modified field after post the form.
Sure a beginner issue but I can´t find it.
Thanks
EDIT:
Select query
public function readOne(){
$query = "SELECT
p.position,
p.modified,
p.modified AS last_modified
FROM positions p
WHERE id = ?
LIMIT 0,1";
$stmt = $this->conn->prepare( $query );
$stmt->bindParam(1, $this->id);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$this->position = $row['position'];
$this->modified = $row['modified'];
$this->last_modified = $row['last_modified'];
}
Update query
public function updatePosition(){
$this->getTimestamp();
$query = "UPDATE positions
SET
position=:position,
modified=:modified,
WHERE id=:id
AND modified=:last_modified";
$stmt = $this->conn->prepare($query);
$this->position=htmlspecialchars(strip_tags($this->position));
$stmt->bindParam(":id", $this->id);
$stmt->bindParam(":position", $this->position);
$stmt->bindParam(":modified", $this->timestamp);
$stmt->bindParam(":last_modified", $this->last_modified);
if($stmt->execute()){
print_r($this->last_modified);
return true;
}
print_r($stmt->errorInfo());
return false;
}
public function getTimestamp(){
date_default_timezone_set('Europe/Berlin');
$this->timestamp = date('Y-m-d H:i:s');
}
I figured it out. The update query and everything else worked fine but the problem was the notification handling, so the function updatePosition() told me everything was updated but it worked as it should and it did not update anything if the value was not the same.
This fixed it:
if($stmt->execute()){
$affected_rows = $stmt->rowCount();
if ($affected_rows == 1) {
return true;
}
This helped me to understand how it works ... PDOStatement::execute() returns true but the data is not updated

PHP/MySQL SET var = var - var

I made a shop for my site, and got it working but realized it was lacking the ability to properly buy an item. to put it into perspective, you don't walk into a store, grab an item, buy it, grab it again, buy it, grab it again, etc. to get as many as you want. you grab them all at once. my site is lacking such feature. So, I have attempted to change the code that takes the stock, and so far am not succeeding.
I've tried the following:
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ?
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - $count
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ".$count."
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
but I cant seem to take the count away from the stock!
The order that you bind parameters should correspond to the order you want to use them in your SQL statement. Here, the item count should come first and the id second. I.e., replace the following line:
$stmt->bind_param("ii", $id, $count);
With:
$stmt->bind_param("ii", $count, $id);

Categories