ON DUPLICATE KEY query - pulling out the primary key of a table - php

I have a query which I would like to INSERT some data into my table however, if there is already data inside of a particular field checkPoint, then run an UPDATE. After a lot of research on here, users have suggested using ON DUPLICATE KEY.
This query works however as apposed to updating an already existing row, it inserts a new one, with a new primary key, please can someone explain where I have gone wrong, or what I've missed out.
<?php
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO `userTakingModule` (`userTakingModuleID`, `idUsers`, `ModuleID`, `checkPoint`) VALUES (NULL, $idUsers, $ModuleID, $checkPoint) ON DUPLICATE KEY UPDATE `idUsers` = VALUES ($idUsers), `ModuleID` = VALUES ($ModuleID), `checkPoint` = VALUES ($checkPoint) ";
$result = $conn -> query($query);
?>
Screenshot of my database layout: the table called userTakingModule in the middle is where the query is applied to.
This is what is happening at the moment as I need to include the Primary Key of userTakingModuleID into the query somehow. (I almost need to say, look for where there is an already existing entry of the same idUser and ModuleID?)

The important part of using INSERT...ON DUPLICATE KEY UPDATE is telling MySQL what the key is, so it can look for duplicates. You said:
I almost need to say, look for where there is an already existing entry of the same idUser and ModuleID
And that's exactly right. You need to create a UNIQUE index on those two columns like so:
ALTER TABLE userTakingModule ADD UNIQUE INDEX(idUser, ModuleID);
Now, conflicts will trigger the update functionality. You should just remove the userTakingModuleID column from your query altogether, it will be given a value automatically as needed. You're also mis-using the VALUES function; you should pass it a column name, and it will resolve to the value that would have been inserted into that column without a conflict. So you can use either the VALUES function, or the variable itself.
And speaking of variables, I would be remiss if I didn't point out how insecure and dangerous it is to insert variables directly into queries. You should always use prepared statements. You don't provide enough code to know which database API you're using, but for PDO it would look like this:
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
$stmt = $conn->prepare($query);
$stmt->execute([$idUsers, $ModuleID, $checkPoint]);
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
And for mysqli something like this (though I'm not too familiar with it)
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
$stmt = $conn->prepare($query);
$stmt->bind_param("iii", $idUsers, $ModuleID, $checkPoint);
$stmt->execute();
$result = $stmt->get_result();

Related

Insert data into database if value doesn't exists in specific column

I've tried to follow several answers on this question but can't seem to get it to work for my specific problem.
I want to insert data but only if the flight_number doesn't exists already. How can I do that?
$sql = mysqli_query($con,
"INSERT INTO space (`flight_number`, `mission_name`, `core_serial`, `payload_id`)
VALUES ('".$flight_number."', '".$mission_name."', '".$core_serial."', '".$payload_id."')"
);
Rob since you saying flight_number is a unique then you can use INSERT IGNORE
<?php
$sql = "INSERT IGNORE INTO space (`flight_number`, `mission_name`, `core_serial`, `payload_id`) VALUES (?,?,?,?)";
$stmt = $con->prepare($sql);
$stmt->bind_param('isss',$flight_number,$mission_name,$core_serial,$payload_id);
if($stmt->execute()){
echo 'data inserted';
// INSERT YOUR DATA
}else{
echo $con->error;
}
?>
OR you could select any row from your database that equal to the provided flight number then if u getting results don't insert.
$sql = "SELECT mission_name WHERE flight_number = ? ";
$stmt = $con->prepare($sql);
$stmt->bind_param('i',$flight_number);
if(mysqli_num_rows($stmt) === 0){
// INSERT YOUR DATA
}
A unique index on flight number should do the trick.
CREATE UNIQUE INDEX flight_number_index
ON space (flight_number);
If you want to replace the existing row with the new one use the following:
$sql = mysqli_query($con,
"REPLACE INTO space (`flight_number`, `mission_name`, `core_serial`, `payload_id`)
VALUES ('".$flight_number."', '".$mission_name."', '".$core_serial."', '".$payload_id."')"
);
Make note that I just copied your code and changed INSERT to REPLACE to make it easy to understand. PLEASE PLEASE PLEASE do not use this code in production because it is vulnerable to injection.
If you don't want to replace the existing row, run an insert and check for errors. If there is an error related to the index, the row already exists.
Disclaimer: I haven't tested any of this code, so there may be typos.

get the id of the last inserted row in mysql

I have looked everywhere and keep getting different answers and incorrect code. All I want to do is after I have added a field to my database in MySQL is to get the user_id of the field that has just been created. I just cannot seem to do it?
I am using this to input the field and thanks for any help. It has a auto_increment value of user_id which is what I need to get.
mysqli_query($con,"INSERT INTO users_accounts (business, email_uniq)
VALUES ('$business', '$email_uniq')");
use this after insert query
$last_row = mysqli_insert_id($con);
You can return the primary key of the last row inserted with
$last_id = mysqli_insert_id($con);
You can find more information here: http://php.net/manual/en/mysqli.insert-id.php
After executing the query, you can use mysqli::$insert_id value or mysqli_insert_id function to retrieve the last generated id, like this:
mysqli_query($con,"INSERT INTO users_accounts (business, email_uniq) VALUES ('$business', '$email_uniq')");
$insert_id = mysqli_insert_id($con);
or using the object functions:
$con->query("INSERT INTO users_accounts (business, email_uniq) VALUES ('$business', '$email_uniq')");
$insert_id = $con->insert_id;
edit: Not related, but definitly important!
If the values for either of these parameters $business or $email_uniq are user supplied, it is highly recommended to make sure they are filtered properly. The easiest way is by using a prepared statement for security (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Here is your code using prepared statements:
$stmt = $con->prepare("INSERT INTO users_accounts (business, email_uniq) VALUES (?,?)");
$stmt->bind_param("ss", $business, $email_uniq);
$stmt->execute();
$insert_id = $con->insert_id;

Php pdo insert query

I need to insert encrypted values in mysql table, but when I use traditional pdo method to insert its inserting the data in wrong format. ex: I insert aes_encrypt(value, key) in place of inserting encrypted value its inserting this as string.
Following is the code :
$update = "insert into `$table` $cols values ".$values;
$dbh = $this->pdo->prepare($update);
$dbh->execute($colVals);
$arr = array("col"=>"aes_encrypt ($val, $DBKey)");
I know i am doing it wrong, but not able to find correct way.
You are almost there, here is a simplified version:
<?php
$sql = "insert into `users` (`username`,`password`) values (?, aes_encrypt(?, ?))";
$stmt = $this->pdo->prepare($sql);
// Do not use associative array
// Just set values in the order of the question marks in $sql
// $fill_array[0] = $_POST['username'] gets assigned to first ? mark
// $fill_array[1] = $_POST['password'] gets assigned to second ? mark
// $fill_array[2] = $DBKey gets assigned to third ? mark
$fill_array = array($_POST['username'], $_POST['password'], $DBKey); // Three values for 3 question marks
// Put your array of values into the execute
// MySQL will do all the escaping for you
// Your SQL will be compiled by MySQL itself (not PHP) and render something like this:
// insert into `users` (`username`,`password`) values ('a_username', aes_encrypt('my_password', 'SupersecretDBKey45368857'))
// If any single quotes, backslashes, double-dashes, etc are encountered then they get handled automatically
$stmt->execute($fill_array); // Returns boolean TRUE/FALSE
// Errors?
echo $stmt->errorCode().'<br><br>'; // Five zeros are good like this 00000 but HY001 is a common error
// How many inserted?
echo $stmt->rowCount();
?>
you can try it like this.
$sql = "INSERT INTO $table (col) VALUES (:col1)";
$q = $conn->prepare($sql);
$q->execute(array(':cols' => AES_ENCRYPT($val, $DBKey)));

PHP insert into database query

I am trying to insert values into a database table, a row is inserted but blank no values are inserted. Only the order_id which is the primary key with auto increment increase.
php code:
<?php
$user_get = mysql_query("SELECT * FROM users");
while($row_user = mysql_fetch_assoc($user_get)){
if($row_user['username'] == $_SESSION['username']){
$row_user['first_name'] = $res1;
$row_user['last_name'] = $res2;
$store_order ="INSERT INTO oko (user, product) VALUES ('$res1', '$res2')";
mysql_query($store_order);
}
}
?>
Your assignments are backwards. I think you meant to:
$res1 = $row_user['first_name'];
$res2 = $row_user['last_name'];
Don't you mean:
$res1 = $row_user['first_name'];
$res2 = $row_user['last_name'];
You could also update the SELECT to have a WHERE clause that checks $_SESSION['username'].
You could also just do an INSERT/SELECT:
INSERT INTO oko (user, product)
SELECT
first_name, last_name
FROM
users
WHERE
username = '$_SESSION["username"]'
Your code is vulnerable to injection. You should use properly parameterized queries with PDO/mysqli

Grab the last insert id from one table to put into another table

probably a simple one for you developers out there
I have this code to insert an order_id and order_name into the 'orders' table:
<?php
// start the session handler
require_once('dbfunction.php');
//connect to database
$conn = DB();
require_once('header.php');
//should we process the order?
if (isset($_POST['process'])) {
$order_name = $_POST['order_name'];
//create initial order
$stmt = $conn2->prepare("INSERT INTO orders (order_name) VALUES (?)");
//bind the parameters
$stmt->bind_param('s', $order_name);
// Execute query
$stmt->execute();
I now want to insert the order items into the order_items table and I cant seem to keep that same ID that was created when inserting into the 'orders' table and add it to the 'order_items' table along with the order_items. Here is my code:
//this gets the most recent auto incremented ID from the database - this is the order_id we have just created
$order_id = mysql_insert_id();
//loop over all of our order items and add to the database
foreach ($_SESSION['order'] as $item) {
$prod_id = $item['prod_id'];
$quantity = $item['quantity'];
$prod_type = $item['prod_type'];
$stmt = $conn2->prepare("INSERT INTO order_items (order_id, prod_id, quantity, prod_type) VALUES (?, ?, ?, ?)");
//bind the parameters
$stmt->bind_param('iiis', $order_id, $prod_id, $quantity, $prod_type);
// Execute query
$stmt->execute();
}
echo "<p class='black'>Order Processed</p>";
I would guess it's because whatever database library you are using is doing something to invalidate the mysql_insert_id (assuming it's even using the mysql functions). I'd suggest you look into the library to find out what method they suggest you use instead.
SQL Server has ##IDENTITY
It looks like mySQL has LAST_INSERT_ID();
My guess is you are using mySQL. If not, then please let me know the version so I can update

Categories