How to ensure that MySQL rows are unique? - php

I am trying to insert a row into a MySQL table, with the condition that the row itself has to be unique.
So for example, the row would have id, name and address, but we can't have an insert with duplicate name and address.
I tried doing a select before inserting, to make sure I don't find the result, but it doesn't seem to be working.
I am currently trying to do this before inserting:
SELECT * FROM locations WHERE cityId = $cityId AND countyId = $countyId AND stateId = $stateId AND countryId = $countyId AND district = $district;
EDIT:
All those fields are allowed to duplicate, they just can't duplicate all at the same time.

The cleanest solution would be to put a UNIQUE constraint on cityId, countyId, stateId, countryId, districtId and then check whether the insert statement was successful.
To quickly test this:
ALTER TABLE your_table_here ADD UNIQUE INDEX(cityId, stateId, countryId, countyId, districtId);
And rerun the insert query. If it encounters a duplicate it will fail, which you will be able to handle in your application.

Assuming you already have a unique index set on the table you can use:
INSERT IGNORE INTO locations SET cityId = $cityId, countyId = $countyId, stateId = $stateId, countryId = $countyId, district = $district;

with such constraints, you should have made the name and address columns as composite primary key..

I think I have a better solution. First check the database and check if the IP and name exists by using:
$check = mysqli_num_rows(mysqli_query($conn, 'SELECT FROM tablename WHERE name="'.$_POST['name'].'"'));
if($check = 0) //Checks if the name does not exist
{
// Your code...
}
else
{
// Error to tell the user the name already exists....
}

Related

prevent duplicate records in mysql table

Im creating a website for booking activities. I have 3 centres. The customer is cant book the same activity twice neither in a different centre. Im using a table in mysql which i store the infos provided by the costumers. Is there any way to filter or to check in my php code if a customer has already booked the same activity more than one time and echo an error msg?
my table(and the info im asking) contains these columns:
ID(Primary)
FirstName
LastName
Email
ContactNumber
ClassName
Week
Intensity
CentreName
$values = $_POST;
foreach ($values as &$value) {
$value = mysql_real_escape_string($value);
}
$sql1="INSERT INTO loan (loan_id)
VALUES ('$values[loan_id]')";
$result = mysql_query($sql1);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
When you create the table add the unique attribute to the fields you want to prevent, something like this
CREATE TABLE Persons
(
P_Id INT NOT NULL AUTO_INCREMENT,
LastName VARCHAR(255) NOT NULL,
FirstName VARCHAR(255),
Address VARCHAR(255),
City VARCHAR(255),
UNIQUE (P_Id)
)
If you already have created the table just edit it like this
ALTER TABLE Persons
ADD UNIQUE (P_Id)
Hope this helps you; If you do not have a unique id i believe this will suit you best on what you need; Note that this is not the full code; You need to add some to other information to fit in your question;
// Checks if the value already exist on the database
$query = SELECT EXISTS(SELECT column_name FROM table_name WHERE
condition LIMIT 1)
// If condition is not met it will proceed with save
if (mysql_num_rows(!$query) > 0) {
echo "Activity Booked";
} else { // If condition is met it will echo an error message
echo "Unable to booked activity"; }
You need to create a unique (composite) index on the column(s) that you wish to be unique. You can disregard your PK when making your unique index. In your case your sql would look something like:
Alter table yourtablename
add unique index idx_unq(`LastName`, `FirstName`, `Email`, `ContactNumber` `ClassName`, `Week`, `Intensity`, `CentreName`);
Then do an INSERT IGNORE INTO instead of an INSERT INTO.
This post may also help you.
"INSERT INTO .. ON DUPLICATE KEY UPDATE" Only inserts new entries rather than replace?
In order to see if record already exist in table you must first "test" to see if that exact record exist in your table. This is to be done before the 'Insert IGNORE Into' in your logic. Using the variables your code would look something like this:
$testcount = "Select count(`LastName`, `FirstName`, `Email`, `ContactNumber` `ClassName`, `Week`, `Intensity`, `CentreName`)
from yourtablename
where
(LastName = '$LastName' AND FirstName= '$FirstName' AND Email= '$EMAIL' AND ContactNumber= '$ContactNumber' AND ClassName= '$ClassName' AND Week= '$Week' Intensity = '$Intensity' AND CentreName = '$CentreName' )";
This query will give you back (assuming there are no duplicates already in the table) a 0 or a 1 and store it in your $testcount variable. This can then be used to either determine based on the value to insert the record into the table or print a message to end user informing them that it already exist.
I am not sure how you want to structure the php code but the psuedocode would look something like:
If $testcount = 1 then do your insert.
else if $testcount = 0 then echo your message.

how to prevent insert duplication data in MySQL

i have this code that work well.
$sql = "INSERT IGNORE INTO phpc_events (cid, owner, subject, description, ctime)
SELECT '1', '1', title, description, start_tdate from at_courses";
mysql_query($sql);
i put this into this page :
> http://localhost/msigilearnv2/tools/calender/copy_database.php
when first runs the page it will copy table from at_courses to phpc_events..
when second runs.. how i can prevent duplication data? because it keep add same data. i put ignore but still not works
I am sharing you one of the alternative. Lets say you have a record in the database and cid value is '1'.
First step check the value if it is already exists in the database.
$sql = "SELECT cid FROM phpc_events";
$returned = mysql_query($sql);
if(mysql_num_rows($returned) > 0){
while( $row = mysql_fetch_array($returned) ){
$PhpcArray [] = $row; //stores result returned in array to ensure less resource used
}
}
$sqlC = "SELECT anotherId FROM at_courses";
$returnedC = mysql_query($sqlC);
if(mysql_num_rows($returnedC) > 0){
while( $rowC = mysql_fetch_array($returnedC) ){
if( in_array( $rowC['anotherId'], $PhpcArray ) ){
// do nothing as id is already exists in phpc_events
}
else{
// do insertion because id in at_courses is not exist yet in phpc_events
}
}
}
Hope this helps.
Another alternative.
By the way you can also try this query if it matches your column as I don't know how your table structure looks like
SELECT cid
FROM at_courses
WHERE cid NOT IN (
SELECT cid FROM phpc_events
)
This query will return the cid in the at_courses which is not yet occur in phpc_events. Then do the insertion for those cid returned from at_courses table.
Thank you.
My MySQL isn't great, but you will need to do something the like:
$sql = "INSERT IGNORE INTO phpc_events (cid, owner, subject, description, ctime)
SELECT '1', '1', title, description, start_tdate from at_courses"
left join phpc_event on phpc_events.cid = at_courses.cid //(and others you want matched for dups
where phpc_events.cid is null
;
If you have a primary key in your tables, you can replace INSERT with REPLACE. This will insert new records or replace them if the primary key already exists.
alter the table by adding UNIQUE constraint
ALTER TABLE phpc_events ADD CONSTRAINT your_field UNIQUE (cid, owner, subject, description, ctime)

Selecting multiple data from a table and inserting into another table using PHP form

I've created a form that submits data into multiple tables. My fields are First Name, Last Name, Email, City/Region/Country and they're all inserted into 3 different tables (User, Email, Location).
The data goes into User and Email just fine, but I'm confused about what to do with Location.
I have 3 separate tables for Location (City, Region, Country). What I want to do is insert CityID, RegionID, and CountryID into the Location table. I have the City/Region/Country field set up so it autocompletes based on the city like this:
My Cities table has all the necessary info (CityID, RegionID, CountryID). How can I pull that data from the Cities table and insert it into my Location table?
Here's part of my code. I'm very very new to PHP and MySQL, so I apologize for the sloppiness of this. The first part of the code works, but the 2nd part doesn't (inserting data into the Location table).
//Insert static values into people table
$sql_user = sprintf("INSERT INTO User (FirstName, LastName,) VALUES ('%s','%s')",
mysql_real_escape_string($_POST['FirstName']),
mysql_real_escape_string($_POST['LastName']),
$result_user = $db->query($sql_user);
//get last inserted userid
$inserted_user_id = $db->last_insert_id();
//Insert values into location table
$sql_city = sprintf("INSERT INTO Location (UserID, CityID, RegionID, CountryID)
VALUES ('$inserted_user_id',(SELECT CityID, RegionID, CountryID, FROM Cities))");
$result_city = $db->query($sql_city);
I figure maybe I need to have "WHERE..." after FROM Cities, but I don't know what my condition would be.
That condition is up to you. If you're taking the value from the input box, it looks like you need to figure out the best way to read the location from the input field. Taking it as is you might want to first break the input into an array:
$location = explode(',',$_POST['location'])
$city = $location[0];
$region = $location[1];
$country = $location[2];
Now in your query -
"...WHERE city_name = '{$city}' AND region_name = '{$region_name}' AND country_name = '{$country}'";
*EDIT
To be more detailed, you need to setup a separate query to get the location by using SQL Joins. Your join combined with the WHERE constraints should return the city you are looking for. So here:
"SELECT Cities.CityID,Cities.RegionID,Cities.CountryID FROM Cities JOIN (Regions,Countries) ON Cities.RegionID = Regions.RegionID AND Cities.CountryID = Countries.CountryID WHERE Cities.CityName = '{city}' AND Regions.RegionName = '{$region}' AND Countries.CountryName = '{$country}' LIMIT 1"
**UPDATE
This is pretty basic stuff that you can get by looking at the PHP manual on MySQL.
http://php.net/manual/en/function.mysql-query.php
Since you're new, I will grant you a pass.
After you run your this query:
$location_result = mysql_query("SELECT Cities.CityID,Cities.RegionID,Cities.CountryID FROM Cities JOIN (Regions,Countries) ON Cities.RegionID = Regions.RegionID AND Cities.CountryID = Countries.CountryID WHERE Cities.CityName = '{$city}' AND Regions.RegionName = '{$region}' AND Countries.CountryName = '{$country}' LIMIT 1");
You need to access the result. So:
while ($row = mysql_fetch_assoc($location_result)) {
$cityID = $location_result['CityID'];
//etc... for each associative column
}
And then in your insert query, insert the $cityID variable for CityID column, etc...

PDO insert into table with foreign keys

I am having a few difficulties with mysql and PDO.
I wish to insert a product into the database, however the product table contains foreign keys. Naturally, I will not know the Foreign key ID when inserting. Am I doing this right??? Is there a better way of tackling this problem?
TABLE Products
Id PK AI int
Name Varchar(20)
CategoryId Int FK
TypeId Int FK
TABLE Categories
Id Int PK
Cat varchar(20)
TABLE Types
Id Int PK
Type varchar(20)
$type = 'Gloves';
$category = 'Clothing';
$sql = 'INSERT INTO Products
SET Name = :name, CategoryId = :catId, TypeId = :typeId
WHERE
CategoryId IN (SELECT Id FROM Categories WHERE Cat = :category) AND
TypeId IN (SELECT Id FROM Types WHERE Type = :type)'
$stmt = $db->prepare($sql);
$stmt->execute(array(':name' => 'Pink childrens gloves', ':category' => $category, ':type' => $type));
As mentioned in a comment below: Normally, I would be getting the ID from a select box. I cannot do this because it will be a script executing the query, not a user.
are you sure that this is what you want?
$sql = 'INSERT INTO Products
SET Name = :name
WHERE
CategoryId IN (SELECT Id FROM Categories WHERE Cat = :category) AND
TypeId IN (SELECT Id FROM Types WHERE Type = :type)'
I think you are trying to use UPDATE
$sql = 'UPDATE Products
SET Name = :name
WHERE
CategoryId IN (SELECT Id FROM Categories WHERE Cat = :category) AND
TypeId IN (SELECT Id FROM Types WHERE Type = :type)'
MySQL allows a combination of SELECT + INSERT in a single query:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
... but I wouldn't care about it. You cannot do proper error checking if you do three different things in a single query.
My advice is that you first validate that there're a category and a type that match the given names. In that step, you can easily get the corresponding IDs, which will let you perform a simple INSERT. Additionally, if you need to insert many products, you can validate first and once.
In addition to #Álvaro G. Vicario's answer, you can also do something like (works in normal sql, I have not tried it with bound variables):
$sql = 'INSERT INTO Products
SET Name = :name,
CategoryId = (SELECT Id FROM Categories WHERE Cat = :category),
TypeId = (SELECT Id FROM Types WHERE Type = :type)';
But I would always check for existing categories and types first, insert where necessary and get the required id's as this will lead to unexpected results if there are no matches in the inner selects.
First of all you need to figure out which is the table that have foreign key data.
Then you need to get all possible values from foreign key table.
Finally you need to build and drop-down list or similar to give ability of select acceptable foreign key.
$q=$db->prepare('SELECT ke.referenced_table_name assoc_table,
ke.referenced_column_name assoc_col FROM
information_schema.KEY_COLUMN_USAGE ke WHERE ke.referenced_table_name IS NOT NULL
AND ke.table_schema=:database AND ke.table_name=:tablename AND ke.column_name=:col');
$q->bindValue(':database','mydatabasename'); //Set your database name here
$q->bindValue(':tablename','Departments'); //Set your table name here
$q->bindValue(':col','City'); //Set the column which foreign key values you want to have here
if($q->execute()) {
$foreingtable=$q->fetch(PDO::FETCH_ASSOC);
$q=$db->prepare('SELECT '.$foreingtable['assoc_col'].' FROM '.$foreingtable['assoc_table']);
if($q->execute())
echo json_encode($q->fetchAll(PDO::FETCH_COLUMN));
}
else {
header('http/1.1 500 Internal Server Error');
print_r($q->errorInfo());
exit;
}
More about this: Get list of possible foreign key values in MySql using PDO

dedupe mysql table but ignore empty values

I have a php script that uploads csv files into a mysql database.
The database has several columns. Among these columns is an 'email' field. I wrote some mysql that would remove rows that contained duplicate values in the email column. Below is the mysql:
$sql = "CREATE TABLE new_table as SELECT * FROM auto WHERE 1 GROUP BY email";
mysql_query($sql, $conn);
$query = mysql_query("SELECT COUNT(*) FROM new_table");
list($number) = mysql_fetch_row($query);
$query = mysql_query("SELECT COUNT(*) FROM auto");
list($number2) = mysql_fetch_row($query);
$result = $number2 - $number;
mysql_query("DROP TABLE auto");
mysql_query("RENAME TABLE new_table TO auto");
The code works, it removes duplicate values.
Problem:
It removes rows that contain no values. So it assumes that two or more emails values that are empty are duplicates and removes they're rows.
Question:
How do I tell mysql to ignore empty values.
Thanks for the help.
Edit
The where is my database table. One table.
The when is when I execute the code. I plan on putting in a php file to be executed on demand.
The result I expect is a mysql table without duplicate emails.
Something like this would work for a one-time alteration, by allowing NULL in email, and adding a UNIQUE constraint:
-- set empties to NULL
UPDATE tablename SET email = NULL WHERE LENGTH(email)=0;
-- drop all rows violating the UNIQUE constraint on email:
ALTER IGNORE TABLE tablename ADD UNIQUE (email);

Categories