I have this function inside a class. The insert is like exactly the same query (but with the INSERT obviously) and it works perfect.
I am trying now to update the database with the properties that the object has and it's not updating, it echoes "Rows not updated" I have tried everything and I have compared my code with examples that work and I dont know why it's not working! It's driving me nuts.
CODE:
public function update() {
$query = "UPDATE ".$this->tablename."
SET
itemtype = :itemtype,
category = :category,
title = :title,
content = :content,
active = :active,
keywords = :keywords,
order = :order,
featured = :featured
WHERE id = ".$this->id;
$this->conn->beginTransaction();
$q = $this->conn->prepare($query);
$q->execute(array(":itemtype"=>$this->itemtype, "category"=>$this->category, "title"=>$this->title,
":content"=>$this->content, ":active"=>$this->active, ":keywords"=>$this->keywords,
":order"=>$this->order, ":featured"=>$this->featured));
if($q->rowCount() > 0) {
echo "Rows updated = ".$q->rowCount()."<br/>";
$return = true;
} else {
echo "Rows not updated<br/>";
$error = $this->conn->errorInfo();
$this->SQLerror = $error[2];
$return = false;
}
$this->conn->commit();
return $return;
}
Just know that the errorInfo returns NULL, like if there was not any SQL Sintax Error!
Put colons here:
"category"=>$this->category, "title"=>
Should be:
":category"=>$this->category, ":title"=>
Make sure, the $this->tablename and $this->id don't lead to any syntax errors.
Update
The word Order is reserved in SQL. Escape it with backticks:
`order` = :order,
You are asking if($q->$q->rowCount() > 0) before commit() see Manual
Related
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
please help me out and sorry for my bad English,
I have fetch data , on basis of that data I want to update the rows,
Follows my code
I fetched data to connect API parameters
<?php
$stmt = $db->stmt_init();
/* publish store for icube*/
$stmt->prepare( "SELECT id,offer_id,name,net_provider,date,visible,apikey,networkid FROM " ."affilate_offer_findall_icube WHERE visible='1' ");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result( $id, $offer_id, $name, $net_provider, $date, $visible,$apikey,$networkid);
$sql = array();
if($rows>0)
{
while($info = $stmt->fetch() ) {
$jsondataicube = file_get_contents('filename/json?NetworkId='.$networkid.'&Target=Affiliate_Offer&Method=getThumbnail&api_key='.$apikey.'&ids%5B%5D='.$offer_id.'');
$dataicube = json_decode($jsondataicube, true);
foreach($dataicube['response']['data'][0]['Thumbnail'] as $key=>$val)
{
$offer_id = $dataicube['response']['data'][0]['Thumbnail']["$key"]['offer_id'];
$display = $dataicube['response']['data'][0]['Thumbnail']["$key"]['display'];
$filename = $dataicube['response']['data'][0]['Thumbnail']["$key"]['filename'];
$url = $dataicube['response']['data'][0]['Thumbnail']["$key"]['url'];
$thumbnail = $dataicube['response']['data'][0]['Thumbnail']["$key"]['thumbnail'];
$_filename = mysqli_real_escape_string($db,$filename);
$_url = mysqli_real_escape_string($db,$url);
$_thumbnail = mysqli_real_escape_string($db,$thumbnail);
$sql[] = '("'.$offer_id.'","icube","'.$_thumbnail.'","'.$_url.'")';
}
}
As I store values which have to be inserted in 'sql'
now
$stmt->prepare( "SELECT offer_id FROM " ."affilate_offer_getthumbnail_icube ORDER BY 'offer_id' ASC");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result($offer_id);
$sqlimplode = implode(',', $sql);
if($rows>0)
{
$query = "UPDATE affilate_offer_getthumbnail_icube WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}`
`
Insert query working well,but how can I update all the data like insert query ?
My Answer is refering to a "set and forget"-strategy. I dont want to look for an existing row first - probably using PHP. I just want to create the right SQL-Command and send it.
There are several ways to update data which already had been entered (or are missing). First you should alter your table to set a problem-specific UNIQUE-Key. This is setting up a little more intelligence for your table to check on already inserted data by its own. The following change would mean there can be no second row with the same value twice in this UNIQUE-set column.
If that would occur, you would get some error or special behaviour.
Instead of using PHPMyAdmin you can use this command to set a column unique:
ALTER TABLE `TestTable` ADD UNIQUE(`tablecolumn`);
After setting up your table with this additional intelligence, you alter your Insert-Command a little bit:
Instead of Insert you can drop and overwrite your Datarow with
REPLACE:
$query= "REPLACE INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100) VALUES (".$sqlimplode.")";
See: Replace Into Query Syntax
Secondly you can do this with the "On Duplicate Key"-Commando.
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
$query= "INSERT INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100)
VALUES (".$sqlimplode.")
ON DUPLICATE KEY UPDATE net_provider = ".$newnetprovider.",
logo2020 = ".$newlogo2020.",
logo100 = ".$newlogo100.";";
Note: I think you missed some ( and ) around your $sqlimplode. I always put them around your implode. Maybe you are missing ' ' around strings as well.
Syntax of UPDATE query is
UPDATE table SET field1 = value1, field2 = value2 ...
So, you cannot pass your imploded array $sql to UPDATE query. You have to generate another sql-string for UPDATE query.
This is clearly incorrect:
$query = "UPDATE affilate_offer_getthumbnail_icube
WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
If the intention is to INSERT offer_id='".$offer_id."' and then UPDATE ... SET offer_id = '".$sqlimplode."'";
You have to use two separate queries, one for INSERT and then another one for UPDATE
An Example:
$query = "INSERT INTO affilate_offer_getthumbnail_icube
(col_name) VALUES('".$col_Value."')";
//(execute it first);
$query2 = "UPDATE affilate_offer_getthumbnail_icube SET
col_name= '".$col_Value."'" WHERE if_any_col = 'if_any_Value';
//(execute this next);
Try this:
$sqlimplode = implode(',', $sql);
if($rows>0)
{
/*$fields_values = explode(',',trim(array_shift($sql), "()"));
$combined_arr = array_combine(['offer_id','net_provider','logo2020','logo100'],$fields_values);
$sqlimplode = implode(', ', array_map(function ($v, $k) { return $k . '=' . $v; }, $combined_arr, array_keys($combined_arr))); */
$query = "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode." ON duplicate key update net_provider = values(net_provider),logo2020 = values(logo2020),logo100 = values(logo100)";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$sqlimplode = implode(',', $sql);
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}
Im having problems getting an update function to work. The function marks badges as seen so that they are hidden from a notification window.
The function is called when the user clicks a button to mark them as seen.
I have two triggers on the table its trying to update which I think may be causing the problem.
The problem is : Can't update table 'users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Triggers:
Function:
function markAsSeen() {
require "connect.php";
$seen = mysqli_query($connection,"Update userbadges
INNER JOIN users ON users.id = userbadges.user_id
SET seen='1'
WHERE studentid = '".$_SESSION["studentid"]."' && seen=0") or die(mysqli_error($connection));
while ($data = mysqli_fetch_array($seen)) {
echo 'Done';
}
}
Is there any way around this?
Your issue is that the update_users_trigger trigger makes changes to the contents of the table users, while the query that is triggering the execution of this trigger also uses the table users.
You will need to adjust your query so that this deadlock doesn't occur. It isn't clear which fields are from each table, but I suspect that in your initial query you need to join on users so that you can query on studentid.
You could create a different function to get the userID that you need something like the following:
require_once "connect.php";
function getUserIDFromStudentID($student_id, mysqli $connection)
{
$query = 'SELECT id FROM users WHERE studentid = ? LIMIT 1';
$stmt = $connection->prepare($query);
// Replace the below s to an i if it's supposed to be an integer
$stmt->bind_param("s", $student_id);
$stmt->execute();
$result = $stmt->get_result();
$record = $result->fetch_object();
$result->free();
if ($record) {
return $record->id;
}
}
function markAsSeen(mysqli $connection) {
$user_id = getUserIDFromStudentID($_SESSION["studentid"], $connection);
if (! $user_id) {
throw new Exception('Unable to get user id');
}
$seen_query = 'UPDATE userbadges SET seen = 1 WHERE user_id = ? and seen = 0';
$stmt = $connection->prepare($seen_query);
// Replace the below s to an i if it's supposed to be an integer
$stmt->bind_param("s", $user_id);
$result = $stmt->execute();
if (! $result) {
die(mysqli_error($connection));
}
echo 'Done';
}
Passing the connection object around rather than requiring a global file to be required every time will allow for more flexibility.
How can I allow the user submitting a form, to update his entry on "re-submission"
for example
12345678910 (unique id) , submitted the form with selections,
12345678910 , re-submitted with new selections
what's the function responsible for "automatically" updating such kind of form entries.
I know that I can use a check if the entry exists, but how do I update it if it exists and insert it in a new row if it doesn't ...
function checkstudentid($studentid)
{
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
if(mysql_fetch_array($result) !== false)
....
// I want to add the entry here since it doesn't exist...with checkboxes
// else , I want to update if it already exists
}
Now I'm also not completely positive if the above code will work...but this is what I have for starters, if there is any other way or if the method I'm using is "wrong" , I would appreciate the heads up...or if what I'm trying to is even possible (the way I'm doing it)...
NOTES
I only have one php file which the form submits to.
I am not using a login/registration system
I do not want to display all the data in a table using HTML, just an
"automatic" update if the studentid already exists in the table
If I were using a deprecated method to interact with a database, I would probably just do this:
<?php
function checkstudentid($studentid) {
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
$query = '';
if (mysql_num_rows($result) > 0) {
$query = "UPDATE table SET column1='$value_one', column2='$value_two' WHERE studentid='$studentid'";
} else {
$query = "INSERT INTO table VALUES('$new_id', '$value_one', '$value_two')";
}
if (mysql_query($query)) {
return true;
} else {
return false;
}
}
?>
But then again, I would use PDO to interact with the DB.
Here is a simple PDO example (you just have to write the function to return the connection):
<?php
function checkstudentid($studentid) {
$update = false;
$dbh = formPDOConnection();
$query = "SELECT studentid FROM table WHERE studentid=:id";
$stmt = $dbh->prepare($query);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
if ($stmt->execute()) {
if ($stmt->rowCount()) {
$update = true;
}
} else {
return 'failure to execute query';
}
// if we just need to update
if ($update) {
$update = "UPDATE table SET value1=:v1,
value2=:v2 WHERE studentid=:id";
$stmt = $dbh->prepare($update);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
} else {
$insert = "INSERT INTO table VALUES(:id,:v1,v2)";
$stmt = $dbh->prepare($insert);
$stmt->bindValue(':id', $new_id, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
}
return $stmt->execute();
}
?>
Save yourself a headache and stop using mysql_*
You can use INSERT... ON DUPLICATE KEY UPDATE... on your mysql code instead use the logic in your PHP.
Here's a sample:
INSERT INTO `category` (`id`, `name`) VALUES (12, 'color')
ON DUPLICATE KEY UPDATE `name` = 'color';
Reference: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
]i'm completely out of idea's as to why the code below does not return the value. I have 2 sql tables that related to one another. Within a class i have the following method, and within the scope of that method all is well. The var dump shows the correct data. The following code is stated in class.php.
public function getId($username, $password) {
if (isset($_SESSION['username'])) {
$sql = "SELECT person_id FROM user WHERE username = ?";
$stmt = $this->dbh->prepare($sql);
$stmt->bindParam(1, $_SESSION['username']);
$stmt->execute();
$id = $stmt->fetch(PDO::FETCH_NUM);
$id = $id[0];
}
ELSE {
echo "Failed to retreive person_id";
}
var_dump($id);
return $id[0];
}
However when i return that value to the showinfo.php which is the main document and state the following:
$user_id = $id[0];
var_dump($user_id);
Then the var dump echoes "NULL". And I need it for the follwing method which is also in class.php.
public function showInfo($user_id) {
$sql = "SELECT * FROM person WHERE person_id = ?";
$stmt = $this->dbh->prepare($sql);
$stmt->bindParam(1, $user_id);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($result as $row) {
echo "<pre>".print_r ($row, true)."</pre>";
}
}
Could anybody be so kind as to show me ways to get this done?
Many thanks in advance for your time and effort in helping me.
I'm guessing you are trying to access the field with the index [0] twice.
Maybe try to return just $id and then access [0] on the outer class.
My PHP is a bit rusty and I don't have access to test right now, but don't you need single quotes around the question mark so it goes to SQL quoted?
i.e.
$sql = "SELECT * FROM person WHERE person_id = '?'";
or
$stmt->bindParam(1, "'" + $_SESSION['username'] + "'");
(but not both!)
so that SQL sees
SELECT * FROM person WHERE person_id = 'MyVal'
instead of
SELECT * FROM person WHERE person_id = MyVal
which it would interpret as a column name
You don't show where the method is called.
You tried this in showinfo.php:
$user_id = $id[0];
Shouldn't this be...
$user_id = getId('someusername', 'somepassword')
Or something similar? Sorry this isn't an answer, but I can't comment.