Related
I've run into some trouble trying to figure out how to update two mysql tables using prepared statements. The first table is updated with the new data but not the second. Can anyone tell me what I've got wrong? Thanks.
/Update Databases
$stmt = $db_conx->prepare('UPDATE tbl_users SET user_name=?, role=?, user_email= ?, company = ?, bio = ?, website = ? WHERE user_id=?');
$stmt->bind_param('sssssss',$user_name,$role,$user_email,$company,$bio,$website,$phone_no, $user_id);
$stmt->execute();
//Update second table
$stmt = $db_conx->prepare('UPDATE useroptions SET user_name=? WHERE user_id=?');
$stmt->bind_param('ss',$user_name,$user_id);
$stmt->execute();
//
if($stmt){
echo
'success";
}
else{ echo "An error occurred!"; }
You have a wrong number of argument in first query 7 ? 7 s but 8 $var ($phone_no )
//Update Databases
$stmt = $db_conx->prepare('UPDATE tbl_users SET user_name=?, role=?, user_email= ?, company = ?, bio = ?, website = ? WHERE user_id=?');
$stmt->bind_param('sssssss',$user_name,$role,$user_email,$company,$bio,$website,$phone_no, $user_id);
^^^^^^
$stmt->execute();
//Update second table
$stmt = $db_conx->prepare('UPDATE useroptions SET user_name=? WHERE user_id=?');
$stmt->bind_param('ss',$user_name,$user_id);
$stmt->execute();
//
I am trying to SELECT data from one table based on the ID and then INSERT the returned data in to another table.
My code is:
<?php
require '../../db-config.php';
if(isset($_POST['course'])) {
$selected_courses = '('. implode(',', $_POST['course']) .')';
$status = 'Live';
$active = 'Y';
$stmt = "SELECT id, coursetitle FROM courses WHERE id IN ". $selected_courses ."
AND status = ?";
$stmt = $conn->prepare($stmt);
$stmt->bind_param('i', $selected_courses);
$stmt->execute();
$stmt->bind_result($id, $coursetitle);
while($stmt->fetch()) {
$stmt = $conn->prepare("INSERT INTO distributor_course_settings
(id, active, coursetitle) VALUES (?, ?, ?)");
$stmt->bind_param("iss", $id, $active, $coursetitle);
$stmt->execute();
}
}
?>
The error I am getting is: PHP Fatal error: Call to a member function
bind_param() on boolean
What is wrong with my code?
you can perform both actions (select and insert) in one query. Something like this:
INSERT INTO distributor_course_settings
(id, distributor, active, coursetitle)
SELECT id, '$distributer', 'Y', coursetitle
FROM courses
WHERE id IN ". $selected_courses ."
AND status = 'Live'
the values in select statement can be anything like string, php variable or a subselet statment like:
INSERT INTO distributor_course_settings
(id, distributor, active, coursetitle)
SELECT id, (select distributer from distributor_course_settings where id = 12), 'Y', coursetitle
FROM courses
WHERE id IN ". $selected_courses ."
AND status = 'Live'
and if its a php variable, you statement could look like this:
$stmt = "INSERT INTO distributor_course_settings
(id, distributor, active, coursetitle)
SELECT id, '".$distributor."', 'Y', coursetitle
FROM courses
WHERE id IN ". $selected_courses ."
AND status = 'Live'"
Ok .. Here is the thing. I want to list users logged on and change their status when logged out. This works perfect. I created a table for that called tblaudit_users. The existing users I SELECT from a tbl_users table.
What I want, is that if an user already exists in the tblaudit_users table it will UPDATE the LastTimeSeen time with NOW(). But instead of updating that record, it creates a new record. This way the table will grow and grow and I want to avoid that. The code I use for this looks like:
+++++++++++++++++++
$ipaddress = $_SERVER['REMOTE_ADDR'];
if(isset($_SESSION['id'])){
$userId = $_SESSION['id'];
$username = $_SESSION['username'];
$achternaam = $_SESSION['achternaam'];
$district = $_SESSION['district'];
$gemeente = $_SESSION['gemeente'];
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' AND active = '1' LIMIT 1");
$query->execute();
foreach($query->fetchAll(PDO::FETCH_OBJ) as $value){
$duplicate = $value->username;
}
if($duplicate != 1){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
");
$insert->execute();
} elseif($duplicate = 1){
$update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE username = '{$username}'");
$update->execute();
} else {
header('Location: index.php');
die();
}
}
I am lost and searched many websites/pages to solve this so hopefully someone here can help me? Thanks in advance !!
UPDATE:
I've tried the below with no result.
+++++
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
ON DUPLICATE KEY UPDATE set LastTimeSeen = NOW(), status = '1'
");
$insert->execute();
Ok. I altered my query and code a little:
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' LIMIT 1");
$query->execute();
if($query){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
ON DUPLICATE KEY UPDATE set LastTimeSeen = NOW(), status = '1'
");
$insert->execute();
} else {
header('Location: index.php');
die();
}
}
I also added a UNIQUE key called pid (primary id). Still not working.
Base on http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html, don't use 'set' in update syntax
example from the page:
INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;
Several issues:
You test on $query, but that is your statement object, which also will be valid even if you have no records returned from the select statement;
There can be issues accessing a second prepared statement before making sure the previous one is closed or at least has all its records fetched;
There is a syntax error in the insert statement (set should not be there);
For the insert ... on duplicate key update to work, the values you provide must include the unique key;
SQL injection vulnerability;
Unnecessary split of select and insert: this can be done in one statement
You can write your test using num_rows(). To get a correct count call store_result(). Also it is good practice to close a statement before issuing the next one:
$query = $db->prepare("SELECT * FROM tblaudit_users
WHERE username = '{$username}' LIMIT 1");
$query->execute();
$query->store_result();
if($query->num_rows()){
$query->close();
// etc...
However, this whole query is unnecessary when you do insert ... on duplicate key update: there is no need to first check with a select whether that user actually exists. That is all done by the insert ... on duplicate key update statement.
Error in INSERT
The syntax for ON DUPLICATE KEY UPDATE should not have the word SET following it.
Prevent SQL Injection
Although you use prepared statements (good!), you still inject strings into your SQL statements (bad!). One of the advantages of prepared statements is that you can use arguments to your query without actually injecting strings into the SQL string, using bind_param():
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district,
gemeente, ipaddress, LastTimeSeen, status)
VALUES (?, ?, ?, ?, ?, ?, NOW(), '1')
ON DUPLICATE KEY UPDATE LastTimeSeen = NOW(), status = '1'
");
$insert->bind_param("ssssss", $userId, $username, $achternaam,
$district, $gemeente, $ipaddress);
$insert->execute();
This way you avoid SQL injection.
Make sure that user_id has a unique constraint in the tblaudit_users. It does not help to have another (auto_increment) field as primary key. It must be one of the fields you are inserting values for.
The above code no longer uses $query. You don't need it.
I found the issue
if(isset($_SESSION['id'])){
$userId = $_SESSION['id'];
$username = $_SESSION['username'];
$achternaam = $_SESSION['achternaam'];
$district = $_SESSION['district'];
$gemeente = $_SESSION['gemeente'];
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE user_id = '{$userId}' LIMIT 1");
$query->execute();
if($query->rowcount()<1){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
");
$insert->execute();
} elseif($query->rowcount()>0) {
$update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE user_id = '{$userId}'");
$update->execute();
} else {
header('Location: index.php');
die();
}
}
Instead of using $username in my query, I choose $userId and it works.
I'm trying to create a sale on a website I'm creating (Think of ebay), the user enters all the input details to create the sell able item, clicks the button and all the info inserts into the db table 'sellingitems' using a prepared statement, now the problem I have is I'm trying to get the users location (State & Suburb) details out of a table (user) and insert that with the prepared statement which all goes into "sellingitems" using SaleState, SaleSuburb in the sellingitems table, the error I get is
" Fatal error: Statement failed! 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 sellingitems (ItemID, UserID, CatID, ItemName, ItemDesc, ItemAmount,' at line 2 in "
I hope this is clear and understandable, I have researched for many hours and cannot find anything on INSERT with a join or some other means to help me, please ask if I need to clarify anything and thank you in advance for helping!!
$stmt = mysqli_prepare($conn, "INSERT INTO sellingitems (ItemID, UserID, CatID, ItemName, ItemDesc, ItemAmount, TimeFrame, ItemCond, Postage, Returns, SaleState, SaleSuburb)
SELECT State, Suburb FROM user WHERE UserID = '$UID'
VALUES ('',?,'',?,?,?, CURRENT_TIMESTAMP,?,?,?,State,Suburb)");
if ($stmt === false) {
trigger_error('Statement failed! ' . htmlspecialchars(mysqli_error($conn)), E_USER_ERROR);
}
$bind = mysqli_stmt_bind_param($stmt, 'issdsssss', $UID, $ItemName, $ItemDesc, $Amount, $ItemCond, $Postage, $Returns);
if ($bind === false) {
trigger_error('Bind param failed!', E_USER_ERROR);
}
$exec = mysqli_stmt_execute($stmt);
if ($exec === false) {
trigger_error('Statement execute failed! ' . htmlspecialchars(mysqli_stmt_error($stmt)), E_USER_ERROR);
}
if ($stmt == false) {
$response = "Sorry something went wrong. : ";
print_r($response);
print_r($stmt->mysqli_error);
print_r($stmt->error);
return;
} else {
$response = "Sale Created.";
print_r($response);
}
That is not the correct syntax for an INSERT SELECT. See the documentation.
Try this instead:
$stmt = mysqli_prepare($conn, "INSERT INTO sellingitems (ItemID, UserID, CatID, ItemName, ItemDesc, ItemAmount, TimeFrame, ItemCond, Postage, Returns, SaleState, SaleSuburb)
SELECT '',?,'',?,?,?, NOW(),?,?,?,State,Suburb FROM user WHERE UserID = '$UID'");
Better still would be to separate the two statements as in the following:
$result = mysqli_query($conn, "SELECT State, Suburb FROM user WHERE UserID = '$UID'");
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$stmt = mysqli_prepare(
$conn,
"INSERT INTO sellingitems (
ItemID,
UserID,
CatID,
ItemName,
ItemDesc,
ItemAmount,
TimeFrame,
ItemCond,
Postage,
Returns,
SaleState,
SaleSuburb)
VALUES
('', ?, '', ?, ?, ?, NOW(), ?, ?, ?, '{$row['State']}', '{$row['Suburb']}')"
);
I can't input the data into my MySQL table using this script:
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
session_start();
include '../scripts/test_ses.php';
include 'connection.php';
$date = date("Y-m-d");
/* Set our params */
$id = $_POST['id'];
$status = $_POST['status'];
$active = 1;
$sql = "INSERT INTO TBL_Holiday (Status, Active, DateOfChange) VALUES (?, ?, ?) WHERE idRequest =$id";
$stmt = $conn->prepare($sql);
/* Bind our params */
$stmt->bind_param('iisi', $status, $active, $date, $id);
/* Execute the prepared Statement */
$stmt->execute();
/* Close the statement */
$stmt->close();
?>
The data of the variables $id, $status is set by a form is there any way to display the php error of the script by alerting it on the form page over ajax ?
remove the $id and WHERE they are used for update or delete a row, in your case insert use below query
$sql = "INSERT INTO TBL_Holiday
(Status, Active, DateOfChange) VALUES
(?, ?, ?)";
or if you wanted to update you need to use below query
$sql = "UPDATE TBL_Holiday SET
Status= ?,
Active= ?,
DateOfChange= ?
WHERE idRequest = ?";
/* Bind our params */
$stmt->bind_param('iisi', $status, $active, $date, $id);
by having its id.. make the update operation..
$sql = "UPDATE TBL_Holiday SET Status='$status', Active='$active', DateOfChange='$date' WHERE idRequest =$id";
otherwise.. make insert by ..
$sql = "INSERT INTO TBL_Holiday (Status, Active, DateOfChange) VALUES ('$status', '$active', '$date')";
Instead of using insert you need to use Update query if you need to use condition while. So your condition will be something like this,
$sql = "UPDATE TBL_Holiday SET Status= ?,Active= ?,DateOfChange=? WHERE idRequest =$id";
You're mixing an INSERT statement with an UPDATE statement
An insert statement is on the form:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3,...);
Where you're creating a new record which is not associated with any other existing rows using a where clause, i.e. you're suppose to skip that part.
Meanwhile an update statement is on the form:
UPDATE table_name
SET column1=value1, column2=value2,...
WHERE some_column=some_value;
Where you do indeed wish to associate your update with some specific row by using a where clause, to indicate which row is to be updated.
Not my favorite sources but you can take a look at insert and update.
This is the working code:
<?php
/* Set our params */
$date = date("Y-m-d");
$id = $_POST['id'];
$status = $_POST['status'];
$active = 1;
/*Create executed SQL*/
$sql = "UPDATE TBL_Holiday SET
Status= ?,
Active =?,
DateOfChange =?
WHERE idRequest = ?";
/*Prepare SQL connection*/
$stmt = $conn->prepare($sql);
/* Bind our params */
$stmt->bind_param('iisi', $status, $active, $date, $id);
/* Execute the prepared Statement */
$stmt->execute();
/* Close the statement */
$stmt->close();
?>