I want to make a code where if the data already exists in the database and the user insert the same input again and send to the database, the sql command will detect it and will not allow the duplicate data enter the database. Addtional information, I don`t have primary key for my table. Here is my code.
$sql="INSERT IGNORE INTO tempahan(Nama,Aktiviti,No_HP,Unit,Tempat,Tarikh_Penggunaan,Masa_Mula,Masa_Akhir,Email) VALUES('$_POST[name]','$_POST[Aktiviti]','$_POST[number]','$_POST[unit]','$_POST[tempat]','$_POST[tarikh]','$_POST[masa1]','$_POST[masa2]','$_POST[email]')";
$_POST['tempat'] = $data['Tempat'] ;
$_POST['masa1'] = $data['Masa_Mula'];
$_POST['masa2'] = $data['Masa_Akhir']; if($_POST['tempat'] != $data['Tempat'] && $_POST['masa1'] != $data['Masa_Mula'] && $_POST['masa2'] != $data['Masa_Akhir']) {
echo 'the booking was successful.';
}
else
{ echo 'the place already occupied.';}
I'm new to sql and also php. Therefore, I really need help from all of you guys. I already see the other same question. But, every solution provided I've failed.
The correct way to do this is to enforce a unique constraint on your table, across the fields that you consider to be unique. You can do that as such.
alter table tempahan
add unique (Tempat, Masa_Mula, Masa_Akhir)
Your database will then reject out of hand any attempts to insert duplicate data. No need to do a prior check before inserting.
Here is a very basic demo of what happens when you set your table up with this unique constraint, and then try and insert duplicate data. In short: it errors.
$query = $db->query( // query your table );
$array = array('name'=>$_POST['name'],
'address'=>$_POST['address']);
while ($row = mysqli_fetch_all($query)) {
$diff = in_array($array, $row);
{
if(empty($diff))
{
// insert data into table
}
else{
//data already exist
}
}
}
// first check existing recors on the database
$select = "SELECT `Tempat`, `Masa_Mula`, `Masa_Akhir`
FROM `tempahan`
WHERE `Tempat` = {$_POST['tempat']}
AND `Masa_Mula` = {$_POST['masa1']}
AND `Masa_Akhir` = {$_POST['masa2']}";
$result = mysql_query($select, $dbconnection);
// check if the have existing records
// the query fetching depends on your work
// but this is a simple way only
// but have more examples on the internet
// to make query more better and ellegant
if (mysql_num_rows($select) > 0) {
echo 'the place already occupied.';
} else {
// insert new record
$sql="INSERT IGNORE INTO tempahan(Nama,Aktiviti,No_HP,Unit,Tempat,Tarikh_Penggunaan,Masa_Mula,Masa_Akhir,Email)
VALUES(
'$_POST[name]',
'$_POST[Aktiviti]',
'$_POST[number]',
'$_POST[unit]',
'$_POST[tempat]',
'$_POST[tarikh]',
'$_POST[masa1]',
'$_POST[masa2]',
'$_POST[email]')";
echo 'the booking was successful.';
}
Related
I am trying to check my database for a key that has already been put in. If the key exists then I need it to check to make sure the username field hasn't been filled. If it has then it needs to throw an error so that it doesn't update and overwrite the information already stored in the database.
Everything works. The update functions etc. the only part that does not work is the checking if the key exists and if the username portion is filled(not sure exactly how to do that) before updating the database.
Thanks,
Cameron Andrews
Code:
// If the Register form has been submitted
$err = array();
if(strlen($_POST['username'])<4 || strlen($_POST['username'])>32){
$err[]='Your username must be between 3 and 32 characters!';
}
if(preg_match('/[^a-z0-9 _]+/i',$_POST['username'])){
$err[]='Your username contains invalid characters!';
}
if(!checkEmail($_POST['email'])){
$err[]='Your email is not valid!';
}
$resultN = mysql_query("SELECT * FROM Users WHERE key='".$_POST['kgen']."'");
while($row = mysql_fetch_array($resultN))//for the results that are returned set the local variables
{
if($_POST['kgen'] == $row['key']){
if($_POST['username'] == $row['usr']){
$err[]='Username already in use';
}
}else if($_POST['kgen'] == ""){
$err[]='Invalid Key Code!';
}else{
$err[]='Error occured please try again';
}
}
if(!count($err)){
// If there are no errors
$_POST['email'] = mysql_real_escape_string($_POST['email']);
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['pass'] = mysql_real_escape_string($_POST['pass']);
// Escape the input data
$theName = $_POST['name'];
$theUser = $_POST['username'];
$thePass = $_POST['pass'];
$theEmail = $_POST['email'];
$theType = "member";
$theRegIP = $_SERVER['REMOTE_ADDR'];
$theDate = "NOW()";
$theKey = $_POST['kgen'];
// If everything is OK register
mysql_query("UPDATE cad.Users SET name = '$theName', usr = '$theUser', pass = '$thePass', email = '$theEmail', type = '$theType', regIP = '$theRegIP', dt = '$theDate' WHERE Users.key = '$theKey'");
Here is how I would approach it:
I would use mysqli or PDO instead of deprecated mysql functions.
I would rewrite all the queries to use prepared statements instead of concatenating your query string together - you have significant SQL injection vulnerability now.
But, since I am not going to rewrite your entire section of code for you, the rest of my approach will be described based on your current mysql/concatenated-query-string approach.
I would put a unique index on name field, but allow NULL value on the field.
I would simply run an update query rather than trying to run an unnecessary select plus an update.
UPDATE cad.Users
SET
name = '$theName',
usr = '$theUser',
pass = '$thePass',
email = '$theEmail',
type = '$theType',
regIP = '$theRegIP',
dt = NOW() /* don't pass 'NOW()' in single quotes as you are currently doing */
WHERE
Users.key = '$theKey'
AND User.name IS NULL;
If you get an error here you should look at error messaging to determine if update failed due to a unique constraint violation (user tried to enter a name that was already used in another record associated with a different key), or some other unexpected reason.
Assuming there was no error, I would then call mysql_affected_rows() (or appropriate equivalent in mysqli or PDO). If the return value is 1, an update was made. If the return value is 0, then no update was made because you did not have any rows that satisfied the WHERE condition.
If you get 0 affected rows, you can re-query the database if you really want to determine if the cause was no matching key or an existing user name.
SELECT name FROM Users WHERE key = '$theKey';
If you get no rows in the result it is because the key is missing, otherwise it is because the name was not a NULL value.
The net is that in the happy path use case, you only make a single query against the database rather than two, with two queries only being necessary if you want to determine the reason no update occurred for those cases. Your current approach always requires 2 queries.
First of all, you should see this. At second, i see, you have strange logic. Try to simplify it. :) As for me, i think it should looks like this:
<?php
if (strlen($_POST['username']) < 4 || strlen($_POST['username']) > 32) {
throw new RuntimeException('Your username must be between 3 and 32 characters!');
} elseif (preg_match('/[^a-z0-9 _]+/i', $_POST['username'])) {
throw new RuntimeException('Your username contains invalid characters!');
} elseif(!checkEmail($_POST['email'])) {
throw new RuntimeException('Your email is not valid!');
} elseif (empty($_POST['kgen'])) {
throw new RuntimeException('Invalid Key Code!');
}
$resultN = mysql_query("SELECT * FROM Users WHERE `key`='{$_POST['kgen']}' AND `usr`='{$_POST['username']}';");
$user = mysql_fetch_array($resultN);
if (!empty($user)) {
throw new RuntimeException('Username already in use');
}
// if all is fine - update
You can use exceptions for checking error. Benefit - you don't go to next check, if failed prev. You also have ability to show user exception message or reason(better use custom exception for this). Negative - you can't get list of errors.
I am importing GMail contacts from Google API and just want to persist unique email ids into database.
Is it possible to insert unique records using codeigniter's Active Record?
Does CodeIgniter provide it out of the box?
If I make the column unique the query throws exception. After digging into documentation I understood that CodeIgniter doesn't provide try catch blocks.
your email field have to be unique in your table indexes.
$query_string = $this->db->insert_string('table', $data);
$query_string = str_replace('INSERT INTO', 'INSERT IGNORE INTO', $query_string);
$req = $this->db->query($query_string);
if($req->affected_rows() == 1) {
//data inserted
} else {
//email exists already
}
If you use the IGNORE keyword, errors that occur while executing the
INSERT statement are treated as warnings instead. For example, without
IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY
value in the table causes a duplicate-key error and the statement is
aborted. With IGNORE, the row still is not inserted, but no error is
issued. Data conversions that would trigger errors abort the statement
if IGNORE is not specified. With IGNORE, invalid values are adjusted
to the closest values and inserted; warnings are produced but the
statement does not abort.
MySQL INSERT syntax
CI Database Helper
You can create a base model (application/core/MY_Model.php) and implement a save function to insert if new and update if exists. Extend your model from it.
This is an extract from http://thephpcode.com/blog/codeigniter/a-smart-codeigniter-model
public function save($data,$tablename="")
{
if($tablename=="")
{
$tablename = $this->table;
}
$op = 'update';
$keyExists = FALSE;
$fields = $this->db->field_data($tablename);
foreach ($fields as $field)
{
if($field->primary_key==1)
{
$keyExists = TRUE;
if(isset($data[$field->name]))
{
$this->db->where($field->name, $data[$field->name]);
}
else
{
$op = 'insert';
}
}
}
if($keyExists && $op=='update')
{
$this->db->set($data);
$this->db->update($tablename);
if($this->db->affected_rows()==1)
{
return $this->db->affected_rows();
}
}
$this->db->insert($tablename,$data);
return $this->db->affected_rows();
}
If your data comes from a from, CI provides a form_validation class that can validate your form on the server side.By form_validation has a rule called is_unique its checks if the given value is already exist on the database or not. you can see a complete and clear explanation here
Or, you can check it manually before inserting your email in that unqiue column.
$this->db->select('email');
$this->db->where(array('email'=>$email));
$query = $this->db->get('yourtable');
if($query->num_rows() > 0){
// the query returned data, so the email already exist.
}else{
// the email not exists, so you can insert it.
}
I am trying to make a database of Users. One user can have an indefinite number of phone numbers. So in the form I’ve created a js function that will give me new input fields and they put the information into a nestled array.
I am doing a double foreach loop to go through my array, and add SQL queries to it based on if the id already exists and just needs to be updated or if it's entirely new and needs to be inserted. I add these SQL queries to a variable $phoneSql . When I echo that variable, it does contain a valid SQL query which works if I try it directly in phpMyAdmin.
This is the foreach loop code:
$phoneSql = 'SELECT id FROM user WHERE id = '.$id.' INTO #id;';
foreach($_POST['phone'] as $key => $value) {
foreach($_POST['user'][$key] as $id => $number) {
if($id == 0 && !$number == ''){
$phoneSql .= 'INSERT INTO phone_number (id, user_id, number) VALUES (NULL, #id, "'.$number.'");';
} else if (!$number == '') {
$phoneSql .= 'UPDATE phone_numbers SET user_id = #id, number = "'.$number.'" WHERE id = '.$id.';';
}
}
}
I have one edit.php page with the form, which posts to update.php where I have the foreach loop from above and following code:
$db->updatePhoneNumber($phoneSql);
It also gets the $id from the user I’m editing at the moment. Then it gets sent to db.php and into this function:
public function updatePhoneNumbers($phoneSql) {
$ phoneSql = $ phoneSql;
$sth = $this->dbh->prepare($phoneSql);
$sth->execute();
if ($sth->execute()) {
return true;
} else {
return false;
}
}
But this is not working. Can I add a variable with sql queries into a function like that or do I have to do it some other way? I’m quite new to this so I’m not sure how to proceed. I’ve tried searching for a solution but haven’t found any. I’m thankful for any advice.
What you should be doing is using an INSERT ... ON DUPLICATE KEY UPDATE ... construct, saving you a lot of that logic.
e.g.
INSERT INTO phone_number (id, user_id, number) VALUES (...)
ON DUPLICATE KEY UPDATE user_id=VALUES(user_id), number=VALUES(number)
With this, no need to select, test, then insert/update. You just insert, and MySQL will transparently convert it into an update if a duplicate key error occurs.
I get Nearest 50 km location names from current location using google api, so it' works fine.
So I need to insert all these locations into my database. If some location already there in database, I need to update these location.
For example I get 10 locations in google api so 5 locations are already there in my database. I need to 5 location are update and remaining 5 locations are insert.
Here is my code:
<?php
require 'dbconnect.php';
$LocaName=$_REQUEST['locname'];
$address=$_REQUEST['address'];
$latt=$_REQUEST['Latt'];
$long=$_REQUEST['Long'];
if($latt && $long)
{
$LocaNamearray = explode("|||", $LocaName);
$addressarray = explode("|||", $address);
$lattarray=explode("|||",$latt);
$longarray=explode("|||",$long);
for($i=0;$i<count($lattarray);$i++)
{
$query1="select * from tbl_MapDetails where Latitude='".$lattarray[$i]."'and Longitude='".$longarray[$i]."'";
$result1=mysql_query($query1);
$now=mysql_num_rows($result1);
}
if($now >=1)
{
for($k=0;$k<count($lattarray);$k++)
{
$query="update tbl_MapDetails set LocationName='".$LocaNamearray[$k]."', Address='".$addressarray[$k]."',Latitude='".$lattarray[$k]."', Longitude='".$longarray[$k]."' where Latitude='".$lattarray[$k]."'and Longitude='".$longarray[$k]."'";
}
$nav="update";
}
else
{
$query ="INSERT INTO tbl_MapDetails(LocationName,Address,Latitude,Longitude) VALUES";
$strDelimiter = "";
for($j=0;$j<count($LocaNamearray);$j++)
{
$name =$LocaNamearray[$j];
$address =$addressarray[$j];
$lat = $lattarray[$j];
$long = $longarray[$j];
$query .= $strDelimiter."('$name', '$address','$lat','$long')";
$strDelimiter = ',';
}
$nav="Add";
}
$result= mysql_query($query);
if($result)
{
echo mysql_error();
$message=array("message"=>"sucessfully".$nav);
}
else
{
echo mysql_error();
$message=array("message"=>"fail".$nav);
}
}
else
{
$message=array("message"=>"require latt and long");
}
echo json_encode($message);
?>
Here insert and update working but I need to check every location in database. There is no location in database. It need to insert other location are update. how to check both these conditions matched locations are update and unmatched locations are inserted Please guide me.
Your logic is wrong in the code. What you are doing is looping through the provided data and for each set of data checking if a location with that lat/long exists and storing it in the $now variable. Once you've finished that loop, you're then checking $now and looping through the provided data again and either INSERTing or UPDATEing each set of data. So if the last set of data exists, your script will try and UPDATE each set of data. If it doesn't, your script will try to INSERT each set of data. Your code should be something like this (mixture of your code and pseudo-code):
for($i=0;$i<count($lattarray);$i++)
{
$query1="select * from tbl_MapDetails where Latitude='".$lattarray[$i]."'and Longitude='".$longarray[$i]."'";
$result1=mysql_query($query1);
$now=mysql_num_rows($result1);
if($now >=1)
{
// update table with location details
}
else
{
// insert location details into table
}
}
If this becomes a performance issue you could look at retrieving all the SELECT data first but if you're only dealing with 10 rows at a time you should be OK.
Note: depending on where your $_REQUEST data is coming from you might want to do some validation, i.e. to check you have matching sets of lat/long/name/address details.
Take a look at MySQL`s ON DUPLICATE KEY UPDATE. But you must be careful, because it is quite slow operation.
But, I think, it would be better if you just union all your SELECT requests in one using OR conditions.
I asked that before, but couldn't figure it out.
I have this form:
<?php
if ( isset ($_REQUEST['fname']{0}, $_REQUEST['lname']{0}, $_REQUEST['mail']{0}, $_REQUEST['url']{0}) ){
$query = "INSERT INTO table1 (url, fname, lname, mail) VALUES ('".$_REQUEST[url]."', '".$_REQUEST[fname]."', '".$_REQUEST[lname]."', '".$_REQUEST[mail]."')";
$result = mysql_query($query)
or die ("Query Failed: " . mysql_error());
}
else{
echo "One Of The Values Not Entered Correctly. Please Press Back In Your Browser And Enter The Missing Values.";
}
?>
And I would like to know if it is possible for it to check if a url exists in the system before entering it again.
Check out MySQL INSERT ... ON DUPLICATE KEY UPDATE, which you can use if you set the URL as unique in your database.
Also, you should make sure to sanitize your inputs before inserting them: http://php.net/manual/en/function.mysql-real-escape-string.php
Replace does exactly what you need.
http://dev.mysql.com/doc/refman/5.0/en/replace.html
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted
Make sure the url column in db is PRIMARY or UNIQUE.
ALTER TABLE `table1` ADD PRIMARY KEY(`url`);
Before you can use this insert function, you must add mysql_connect(), mysql_select_db()
function insert($post = array(), $tb, $announce=true, $ignore="",$updateonduplicate=false){
foreach($post as $k => $v){
$fields[$k] = $v;
$values[] = mysql_real_escape_string($v);
}
$query = "INSERT {$ignore} INTO `{$tb}` (`".implode("`,`",array_keys($fields))."`)"." VALUES ('".implode("','",$values)."')";
if($updateonduplicate !== false){
$query .= " ON DUPLICATE KEY UPDATE ";
$countfields = 0;
foreach($fields as $field => $value){
$query .= " `".$field."`='".$value."'";
$countfields++;
if(count($fields) !== $countfields)
$query .= ",";
}
}
//mysql_connect(), mysql_select_db()
// assuming db is connected, database selected
$result = mysql_query($query)
if($announce !== true)
return;
if(!$result){
$announce = "Query Failed: " . mysql_error();
}else{
$announce = "insert_success";
}
if($updateonduplicate === true && $result === 0 && mysql_affected_rows() >=1){
$announce = "update_success";
}
return $announce;
}
$post = array();
$post['url'] = $_REQUEST[url];
$post['fname'] = $_REQUEST[fname];
$post['lname'] = $_REQUEST[lname];
$post['mail'] = $_REQUEST[mail];
insert($post,"table1",true,"",true);
If you do have a UNIQUE or PRIMARY KEY index on the url column, INSERT IGNORE will do what you want. New rows will go in and duplicates will be ignored. INSERT ... ON DUPLICATE KEY UPDATE will allow you to update if there's a duplicate, if that's what you want to do. Also, pay good attention to the SQL injection comments from the others here.
Given the description in the OP and subsequent comments (try insert, throw error if exists), I'd simply make sure the required "unique" columns had unique constraints or were part of the primary key.
Then, simply attempt the insert and catch / handle any unique constraint violation errors. This is quicker than checking for existing records.
Using PDO with the error mode set to throw exceptions means you can wrap this code nicely in a try catch block. From memory, unique constraint violations set the exception code to something you can test against.