Prevent Duplicate Insert - php

I have a page which is doing an insert. The DB table has a unique column called "order" that auto increments upon adding a new row. I am executing the insert in this way:
$insert = <<<SQL
INSERT INTO `order` (name, email, team, project, startdate, enddate, comment, server) VALUES (?,?,?,?,?,?,?,?);
SQL;
$instat = $mysqli->prepare($insert);
$bind = mysqli_stmt_bind_param($instat, "ssssssss", $name, $email, $team, $project, $timestart, $timeend, $comment, $code);
$exec = mysqli_stmt_execute($instat);
mysqli_stmt_close($instat);
mysqli_close($mysqli);
I am allowing the DB to handle an auto increment of the order column so that it cannot be duplicated. This works just fine, but if I were to hit refresh on the page, it will insert another row with the same data on a new unique order id. How can I prevent another insert upon a page refresh?

After saving the row, redirect the page to another page with corresponding message . Your flow will be like
1) $service->saveObject($dataObject);
2) redirect_to_success page.

before every insert - make select query and check
Make insert query with NOT EXIST:
How to 'insert if not exists' in MySQL?
MySQL: Insert record if not exists in table
3.Redirect to current page after insert.

Related

Inserting data into multiple tables not functioning correctly

I have the following two tables
Table player:
player_id (int)(primary)
player_name (varchar)
player_report_count (int)
Table report:
report_id (int)(primary)
player_id
report_description
report_location
Firstly I ask the user for the player_name and insert it into the player database. From here the player is given an id.
Then I tried to grab the value of the players report count and increment the current value by one (which isn't working).
This is followed by grabbing the playerId from the player table and then inserting into the corresponding column from the report table (also does not work).
When I insert some values into the database, the names, description and report are added to the database however the playerID remains at 0 for all entries and the player_report_count remains at a consistent 0.
What is the correct way to make these two features function? And also is there a more efficient way of doing this?
<?php
$records = array();
if(!empty($_POST)){
if(isset($_POST['player_name'],
$_POST['report_description'],
$_POST['report_location'])){
$player_name = trim($_POST['player_name']);
$report_description = trim($_POST['report_description']);
$report_location = trim($_POST['report_location']);
if(!empty($player_name) && !empty($report_description) && !empty($report_location)){
$insertPlayer = $db->prepare("
INSERT INTO player (player_name)
VALUES (?)
");
$insertPlayer->bind_param('s', $player_name);
$reportCount = $db->query("
UPDATE player
SET player_report_count = player_report_count + 1
WHERE
player_name = $player_name
");
$getPlayerId = $db->query("
SELECT player_id
FROM player
WHERE player_name = $player_name
");
$insertReport = $db->prepare("
INSERT INTO report (player_id, report_description, report_location)
VALUES (?, ?, ?)
");
$insertReport->bind_param('iss', $getPlayerId, $report_description, $report_location);
if($insertPlayer->execute()
&& $insertReport->execute()
){
header('Location: insert.php');
die();
}
}
}
Main issue here is you are getting player details before inserting it. $getPlayerId will return empty result always.
Please follow the order as follows.
Insert player details in to player table and get payerid with mysql_insert_id. After binding you need to execute to insert details to the table.
Then bind and execute insert report .
Then update the player table by incrementing report count with playerid which you got in step 1.
Note : use transactions when inserting multiple table. This will help you to rollback if any insert fails.
MySQL Query will return result object. Refer it from here https://stackoverflow.com/a/13791544/3045153
I hope it will help you
If you need to catch the ID of the last insterted player, This is the function you need if you're using PDO or if it's a custom Mysql Class, you need the return value of mysql_insert_id() (or mysqli_insert_id()) and then directly use it in the next INSERT INTO statement

Moving records to a new table updating original id accordingly

I need to create a new table with certain data from another table but update the original table with the ID of the newly inserted record from the new table. Like so:
NEW_TABLE
----------------
id
-- other data --
ORIGINAL_TABLE
----------------
id
new_table_id
-- other data --
However, the added records to new_table will be grouped to get rid of duplicates. So, it won't be a 1-to-1 insert. The query needs to update matching records, not just the copied record.
Can I do this in one query? I've tried doing a separate UPDATE on original_table but it's not working.
Any suggestions?
You are going to be doing 3 seperate queries as I see it.
$db = new PDO("...");
$stmt = $db->prepare("SELECT * FROM table");
$stmt->execute();
$results = $stmt->fetchAll();just iterate o
foreach ($results as $result) {
$stmt = "INSERT INTO new_table (...) VALUES (...)";
$stmt = $pdo->prepare($stmt);
$data = $stmt->execute();
$insert_id = $pdo->lastInsertId();
// Update first table
$stmt = "UPDATE table SET id=:last WHERE id=:id";
$stmt = $pdo->prepare($stmt);
$data = $stmt->execute(array('last' => $insert_id, 'id' => $result['id']));
}
The above is a global example of your workflow.
You can use temporary tables or create a view for NEW_TABLE.
Temporary Tables
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current session, and is dropped automatically when the session is closed. This means that two different sessions can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.) To create temporary tables, you must have the CREATE TEMPORARY TABLES privilege.
--Temporary Table
create temporary table NEW_TABLE as (select * from ORIGINAL_TABLE group by id);
Views
Views (including updatable views) are available in MySQL Server 5.0. Views are stored queries that when invoked produce a result set. A view acts as a virtual table. Views are available in binary releases from 5.0.1 and up.
--View
create view NEW_TABLE as select * from ORIGINAL_TABLE group by id;
The view will always be updated with the values in ORIGINAL_TABLE and you will not have to worry about having duplicate information in your database.
If you do not want to use the view, I believe you can only perform an insert on one table at a time unless you have some sort of view that would allow you to do both, but you probably want to do it as two steps in a transaction
First you will have to tell the database that you want to start a transaction. Then you will perform your operations and check to see if they were successful. You can get the id of last inserted row (this assumes you have an auto_increment field) to use in the second statement. If both statement seem to work fine, you can commit the changes, or if not, rollback the changes.
Example:
//Assume it will be okay
$success = true;
//Start the transaction (assuming you have a database handle)
$dbh->beginTransaction();
//First Query
$stmt = "Insert into ....";
$sth = $dbh->prepare($stmt);
//See if it works
if (!$sth->execute())
$success = false;
$last_id = $dbh->lastInsertId();
//Second Query
$stmt = "Insert into .... (:ID ....)";
$sth = $dbh->prepare($stmt);
$sth->bindValue(":ID", $last_id);
//See if it works
if (!$sth->execute())
$success = false;
//If all is good, commit, otherwise, rollback
if ($success)
$dbh->commit();
else
$dbh->rollBack();

Insert id from from one table and insert it into another one. Mysql + PHP [duplicate]

This question already has answers here:
How to get the last field in a Mysql database with PHP?
(5 answers)
Closed 9 years ago.
I am working on a register user form and I have two tables in mysql. What I want to do is when a new user has registered, take the id (which primary key) of that user and insert it into another table. What is the best way to do that?
Thanks in advance.
You need to use mysql_insert_id for this purpose. Here is an example:
<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf("Last inserted record has id %d\n", mysql_insert_id());
?>
First insert the user details into users table and get inserted user id using mysql_insert_id. and use that user id to insert into another table.
AS ON GETTING IT ON PHP
GET LAST INSERT ID HERE
BUT IF YOU INTEND TO GET IT USING MYSQL QUERY
use stored procedure to store last insert id to a variable then generete your second query
INSERT INTO T1 (col1,col2) VALUES (val1,val2);
SET #last_id_in_T1 = LAST_INSERT_ID();
INSERT INTO T2 (col1,col2) VALUES (#last_id_in_T1,val2);
or direct insert after your first insert
INSERT INTO T1 (col1,col2) VALUES (val1,val2);
INSERT INTO T2 (col1,col2) VALUES (LAST_INSERT_ID(),val2);
Use any of transaction query for writing:
Following is in CI pattern:
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->query('AN SQL QUERY...');
if(!$this->db->trans_complete()){
$this->db->trans_rollback();
}
$query1= "INSERT INTO employee ( username, email,...)
VALUES ('".$_POST["username"]."', ...)";
if($result1 = mysql_query($query1))
{
$emp_id = mysql_insert_id(); // last created id by above query
$query2= "INSERT INTO dept ( emp_id, dept_name, ...)
VALUES ('".$emp_id."', '".$_POST["dept_name"]."',...)";
if($result2 = mysql_query($query2))
{
//success msg
}
}
Another neat way to do it at do it at Database level itself is to used Stored Procedure
Look at this solution to see an example of how to do it. You will have to check how Stored procedures work in your specific database to get the specific syntax. This makes it error free even if someone refactors or moves around the code and more efficient.
Using trigger the Mysql on database-level. For example, I have two tables:
user(id int primary key, nombre varchar(50));
replication(id_r int primary key, nombre_r varchar(50));
Using the trigger:
create trigger user_r after insert on user
for each row
insert into replication(id_r, nombre_r)
select u.id, u.nombre
from user u
where u.id=NEW.id and u.nombre=NEW.nombre;

Linking existing MySQL records in new query, PHP/PDO

$insert = $dbh->prepare('INSERT INTO tags (tag_name) VALUES (:tag)');
$insert->bindParam(':tag', $tag, PDO::PARAM_STR);
foreach($tags as $tag) {
$insert->execute();
$tag_id = $dbh->lastInsertID();
echo $tag_id."+".$photo_id."<br />";
$sql = "INSERT INTO tagrefs (tag_id, photo_id) VALUES (:tag_id,:photo_id)";
$q = $dbh->prepare($sql);
$q->execute(array(':tag_id'=>$tag_id,
':photo_id'=>$photo_id));
}
This particular piece of code inserts tags related to uploaded photos into a table called 'tags'. It links the tag_id to the photo_id in a table called 'tagrefs'. This all works fine, until I use a tag twice. Which is logical, because nothing is inserted (tags are unique, I simply want the entry in 'tagrefs' to list the photo_id for my next photo with tag_id's that already exist)
How do I make it so that my code compares the tags the user put in and compares them, or that the values of existing tags are returned and put into 'tagrefs' properly? Thank you very much in advance for your time.
If you use INSERT ... ON DUPLICATE KEY UPDATE, then lastInsertID() will return the AUTO_INCREMENT field's value of a matched row even if an UPDATE is performed instead of an insertion.
To ensure that it also works in versions of MySQL prior to v5.1.12, one can explicitly set the insertion id with MySQL's LAST_INSERT_ID() function:
INSERT INTO tags
(tag_name)
VALUES
(:tag)
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID(id)

How to check to see if a key exists before trying to insert it into a database?

I'm pulling data from a calendar feed and each event in the calendar has a unique $EventID string. I'm using PHP.
I have a SQL database with an Event_ID column. These IDs are strings. I need to be able to compare my $EventID against the Event_ID column and put in in the database if it's not there.
I have a primary key set up to auto increment in the database, and I was thinking I can set up a loop to increment through those and compare each to the $EventID, but I'm wondering if there is a better way-maybe a PHP function I don't know about?
I've got a whole lot of code, but basically I've got:
<?php
$EventID = $event->id; //This is the event ID
mysql_query("INSERT INTO myTable
(Event_ID, Date_added, Date_edited)
VALUES
('$EventID', '$dateAdded', '$lastEdited')");
?>
So how do I set up a conditional to check all the Event_IDs that are already in the database against the $EventID?
$query = "SELECT * FROM `myTable` WHERE `Event_ID`='$EventID' ";
$result = mysql_query($query);
if (!mysql_num_rows($result))
// INSERT QUERY
Check if the Event ID is present, If not insert it
You could just skip the "Select" query and do an "INSERT IGNORE" instead:
mysql_query("INSERT IGNORE INTO myTable
(Event_ID, Date_added, Date_edited)
VALUES
('$EventID', '$dateAdded', '$lastEdited')");
this will leave existing Event_id's, and just add new records if required.

Categories