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'"
Related
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']}')"
);
Is it possible to have a "mixed" SQL Insert like the following?
I want to be able to get one value from another table (that needs a param) and then enter in 2 more params.
$sql = "INSERT INTO tblquestions (userID, questionText, questionAnswer) VALUES (
Select userID FROM tblusers WHERE userEmail = (?),?,?)";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'sss', $userEmail, $question, $answer);
$result = mysqli_stmt_execute($stmt);
if (!$result) {
throw new Exception($conn->error);
}
It is unnecessary. Just use insert . . . select:
INSERT INTO tblquestions(userID, questionText, questionAnswer)
Select userID, ?, ?
FROM tblusers
WHERE userEmail = (?);
I'm trying to get the last inserted id of multiple inserted rows.
record_id is auto increment
$sql = "INSERT INTO records (record_id, user_id, status, x) values ";
$varray = array();
$rid = $row['record_id'];
$uid = $row['user_name'];
$status = $row['status'];
$x = $row['x'];
$varray[] = "('$rid', '$uid', '$status', '$x')";
$sql .= implode(',', $varray);
mysql_query($sql);
$sql2 = "INSERT INTO status_logs (id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES";
$varray2[] = "(' ', mysql_insert_id(), '$status', '$uid', '$x')";
$sql2 .= implode(',', $varray2);
mysql_query($sql2);
This is the result:
INSERT INTO records (record_id, user_id, notes, x) values ('', '1237615', 'this is a note', 'active')
INSERT INTO status_logs (log_id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES('', INSERT INTO records (record_id, user_id, notes, x) values ('', '1237615', 'this is a note', 'active')
INSERT INTO status_logs (log_id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES('', mysql_insert_id(), '1', '2013:05:16 00:00:01', '', this is a note'', '1237615', 'active'), '1', '2013:05:16 00:00:01', '', this is a note'', '1237615', 'active')
There is no value for mysql_insert_id().
You're mixing php function mysql_insert_id() and SQL INSERT statement syntax.
Either use MySQL function LAST_INSERT_ID() in VALUES clause of INSERT statement
INSERT INTO records (user_id, notes, x) VALUES('1237615', 'this is a note', 'active');
INSERT INTO status_logs (record_id, status_id, date, timestamp, notes, user_id, x)
VALUES(LAST_INSERT_ID(), '1', ...);
^^^^^^^^^^^^^^^^^
or retrieve the last inserted id by making a separate call to mysql_insert_id() right after first mysql_query(). And then use that value when you as a parameter to your second query.
$sql = "INSERT INTO records (user_id, ...)
VALUES(...)";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error()); //TODO beter error handling
}
$last_id = mysql_insert_id();
// ^^^^^^^^^^^^^^^^^^
$sql2 = "INSERT INTO status_logs (record_id, ...)
VALUES $last_id, ...)";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error()); //TODO beter error handling
}
Note:
You don't need to specify auto_incremented column in column list. Just omit it.
Use at least some sort of error handling in your code
On a side note: Instead of interpolating query strings and leaving it wide open to sql-injections consider to use prepared statements with either mysqli_* or PDO.
Unless I mis-reading your code, you're calling the PHP function mysql_insert_id from within the SQL?
What you need to do is grab that into a PHP variable first, then use the variable in the SQL. Something like this:
// Run the first query
mysql_query($sql);
// Grab the newly created record_id
$recordid= mysql_insert_id();
Then in the second INSERTs just use:
$varray2[] = "(' ', $recordid, '$status', '$uid', '$x')";
$fname = addslashes($fname);
$lname = addslashes($lname);
$dob = addslashes($dob);
$email = $_POST['email'];
$sql =
"INSERT INTO subscriber
(fname, lname, dob)
VALUES
('".$fname."', '".$lname."', '".$dob."')
WHERE email='".$email."'";
$register = mysql_query($sql) or die("insertion error");
I am getting error in sql query "insertion error". Query is inserting data into DB after removing WHERE statement. What is the error.
You can't use where in an insert statement. You might be thinking of an update instead?
$sql = "update subscriber set fname='".$fname."', lname = '".$lname."', dob = '".$dob."' WHERE email='".$email."'";
If your email is a unique value, you can also combine an insert with an update like this:
insert into
subscriber (fname, lname, dob, email)
values ('".$fname."', '".$lname."', '".$dob."', '".$email."')
on duplicate key update set fname='".$fname."', lname='".$lname."', dob='".$dob."'
This second syntax will insert a row if there isn't one with a matching email (again, this has to be set to a unique constraint on the table) and if there is one there already, it will update the data to the values you passed it.
Basically INSERT statement cannot have where. The only time INSERT statement can have where is when using INSERT INTO...SELECT is used.
The only syntax for select statement are
INSERT INTO TableName VALUES (val1, val2, ..., colN)
and
INSERT INTO TableName (col1, col2) VALUES (val1, val2)
The other one is the
INSERT INTO tableName (col1, col2)
SELECT col1, col2
FROM tableX
WHERE ....
basically what it does is all the records that were selected will be inserted on another table (can be the same table also).
One more thing, Use PDO or MYSQLI
Example of using PDO extension:
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
?>
this will allow you to insert records with single quotes.
Oops !!!! You cannot use a WHERE clause with INSERT statement ..
If you are targeting a particular row then please use UPDATE
$sql = "Update subscriber set fname = '".$fname."' , lname = '".$lname."' , dob = '".$dob."'
WHERE email='".$email."'";
$register = mysql_query($sql) or die("insertion error");