How to avoid duplicate entry in mysql with php - php

Here i have made a function to produce random key,
function gen_link(){
$link = '';
$s = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
for ($i= 0 ; $i <= 4 ; $i++)
$link = $link.$s[rand(0,63)];
return $link;
}
I dont want to repeat the key in mysql table, i have made it unique in mysql, but what i want to do is, when the key already exists i want to regenerate another random key and try to add it to table again, i tried this code below.
$con = mysqli_connect("localhost","shashi","asd123","redir");
$sql = " insert into 'links' ('link') values('$link') ";
do{
$link = gen_link();
$result = mysqli_query($con,$sql);
}while(mysqli_errno($con)==1064);
mysqli_close($con);
but it doesn't seem to work at all, it keeps looping. what can i do?

Instead of generating an actual error, use an INSERT IGNORE query like this:
$sql = "insert ignore into `links` (`link`) values ('$link')";
And check mysqli_affected_rows() to ensure something was actually inserted:
while (mysqli_affected_rows($con) == 0);
All together, that looks like this:
$con = mysqli_connect("localhost", "shashi", "asd123", "redir");
do {
$link = gen_link();
$sql = "insert ignore into `links` (`link`) values ('$link')";
$result = mysqli_query($con, $sql);
} while (mysqli_affected_rows($con) == 0);
mysqli_close($con);
Also, a couple notes about your queries:
I changed your quotes around the table and column names to backticks, which is the correct way to quote them in sql.
Because you're including the $link variable directly in the query, you need to define your query after you give the $link variable a value - so I moved that line inside the loop. This is probably the source of your original problem where you kept looping.
It's not important in this instance because you have full control of the value you're inserting (generated in gen_link()), but it's a good idea to get in the habit of properly escaping the variables you insert into a query. Alternatively, read up a bit on prepared statements, and use them instead.

Get the existing key values from the DB as array. Then search your current key with your existing keys using in_array() function. If it is true generate new key. If the condition is false , insert your new key.
http://php.net/manual/en/function.in-array.php
if(in_array($new_key,$existing))
{
//generate new key
}
else
{
//insert current key
}

I'm working with Prepared Statement an using "ON DUPLICATE KEY", to change the duplicate Value with MYSQL:
$sql = "INSERT INTO ".$this->table." ".
"(".implode(',',$fields).") VALUES
(".implode(',',$values).")
ON DUPLICATE KEY
UPDATE key_field = concat(substr(key_field,1,".($laenge_key-3)."),FORMAT(FLOOR(RAND()*999),0))

Related

Check for existing name in the database

This is my code when I want to add an operation, but it doesn't check for an existing operation that is already in the database, is there any way to do so?
code below:
<?php
include('db_conn.php');
$operationname = $_POST['operationname'];
$cost = $_POST['cost'];
$sql = "INSERT INTO operation(operationname,cost) VALUES('$operationname', '$cost')";
$query = mysqli_query($con, $sql);
if($query==true){
$data = array(
'status'=>'success',
);
echo json_encode($data);
} else {
$data = array(
'status'=>'failed',
);
echo json_encode($data);
}
?>
First of all, as #gertjanknappen already mentioned: make operationname unique in the database, it actually looks like a good candidate for being the tables primary key.
That way the database will prevent duplicate inserts. Next what is your actual goal: just preventing duplicate entry, or also updating cost in case a row for operationname already exists?
In the later case
$sql = "INSERT INTO operation(operationname,cost) VALUES('$operationname', '$cost') ON DUPLICATE KEY UPDATE cost='$cost'";
in combination with a unique or primary key constraint on operationmame should give you what you are looking for.
PS: the way you construct your query string from user input is a sure recipe for SQL injection attacks, so you may also want to read up on prepared statement parameter binding, or at least on how to properly validate and escape user input ...

Proper way to manipulate database

My entry form I have an inventory database with tables like aluminium, iron etc... Each table contains a subcategory of items like aluminium_pala, iron_1.5inch and so on. The entry code is like this:
include("dbConnect.php");
$orderNo = $_POST["number"];
if(isset($_POST["mat1"])&&$_POST["mat1"]!=NULL)
{
$mat1 = $_POST["mat1"];
$selmat1 = $_POST["selmat1"];
$amtmat1 = $_POST["amtmat1"];
$query = "INSERT INTO $mat1 ($selmat1,orderNo) VALUES (-$amtmat1,$orderNo);";
if(!($result = $mysqli->query($query)))
print "<div class='error'>insertion failed. Check your data</div>";
}
if(isset($_POST["mat2"])&&$_POST["mat2"]!=NULL)
{
$mat2 = $_POST["mat2"];
$selmat2 = $_POST["selmat2"];
$amtmat2 = $_POST["amtmat2"];
$query = "INSERT INTO $mat2 ($selmat2,orderNo) VALUES (-$amtmat1,$orderNo);";
if(!($result = $mysqli->query($query)))
print "<div class='error'>insertion failed. Check your data</div>";
}... and it goes on till mat11
I am trying to collect each similar table (mat1, mat2..) and their corresponding item (selmat1, selmat2...) and bunch the all in one query. That is, instead of going
INSERT INTO al_openable (zPala,orderNo) VALUES (23,14);
INSERT INTO al_openable (outer,orderNo) VALUES (50,14);
I am trying to execute it like
INSERT INTO al_openable (zPala,outer,orderNo) VALUES (23,50,14);
I need this to avoid duplicate foreign key entry(for $orderNo). One idea I've been considering is to use UPDATE if the order number is pre-existing. Do you guys think this is a good idea? And if so, what will be the best way to execute it? If not, how would a more experienced programmer solve this conundrum?
I think this question is related to your query: Multiple Updates in MySQL
You may use ON DUPLICATE KEY UPDATE in combination with INSERT statement.

ON DUPLICATE KEY UPDATE creating new records

I am having problems with the following code, it seems to work and creates the records just fine, the problem is each time I hit submit, instead of it updating the record it just creates a new one. If I turn off auto incremental for the primary key it updates the record just fine but then doesn't create any new ones, it seems either one or the other :-S
<?php
$query = mysql_query("
INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
('$_POST[cf_id]','$_POST[cf_uid]','$_POST[emailformname]','$_POST[datesent]')
ON DUPLICATE KEY UPDATE
datesent='$_POST[datesent]';
") or die(mysql_error());
?>
did you already try to echo your query string? guess the variable replacement inside it is wrong. try something like that for debugging:
<?php
$sql = "INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
('{$_POST['cf_id']}','{$_POST['cf_uid']}','{$_POST['emailformname']}','{$_POST['datesent']}')
ON DUPLICATE KEY UPDATE
datesent='{$_POST['datesent']}'";
echo $sql; // for debugging
$query = mysql_query($sql) or die(mysql_error());
?>
Note the corrected variable names above. (curly braces around it, quotes around the array index)
I can't imagine it's the problem, but does the same thing happen when you cast the ID to an int and leave out the quotes?
<?php
$query = mysql_query("
INSERT INTO hqfjt_chronoforms_data_emailform
(cf_id,cf_uid,emailformname,datesent)
VALUES
(" . (int) $_POST['cf_id'] . ",'$_POST[cf_uid]','$_POST[emailformname]','$_POST[datesent]')
ON DUPLICATE KEY UPDATE
datesent='$_POST[datesent]';
") or die(mysql_error());
?>
By the way, you really shouldn't use your $_POST variables in your query without mysql_real_escape_string or better yet, use prepared statements (PDO or mysqli).

Wrong mysql query in php file?

I'm trying to insert some data into my mysql database. The connection is working fine but im having a problem with sending the query correctly to the database. Below you can find the code in my php file. I also post what for type of fields they are in the Database.
Fields in the mysql database:
Reservaties_id = int
Materialen_id = int
aantal = int
effectief_gebruikt = tinyint
opmerking = Varchar2
datum_van = date
datum_tot = date
$resID = $_REQUEST['resID'];
$materialen_id = $_REQUEST['materialen_id'];
$aantal = $_REQUEST['aantal'];
$effectief_gebruikt = $_REQUEST['effectief_gebruikt'];
$opmerking = $_REQUEST['opmerking'];
$datum_van = date('YYYY-MM-DD',$_REQUEST['datum_van']);
$datum_tot = date('YYYY-MM-DD',$_REQUEST['datum_tot']);
$string = "INSERT INTO `materialen_per_reservatie`(`reservaties_id`, `materialen_id`, `aantal`, `effectief_gebruikt`, `opmerking`, `datum_van`, `datum_tot`) VALUES ($resID, $materialen_id, $aantal, $effectief_gebruikt, '$opmerking', $datum_van, $datum_tot)";
mysql_query($string);
you have to include single quotes for the date fields '$dataum_van'
$string = "INSERT INTO `materialen_per_reservatie`(reservaties_id, materialen_id, aantal, effectief_gebruikt, opmerking, datum_van, datum_tot) VALUES ($resID, $materialen_id, $aantal, $effectief_gebruikt, '$opmerking', '$datum_van', '$datum_tot')";
and this is only a example query, while implementing don't forget to sanitize your inputs
Your code has some serious problems that you should fix. For one, it is not doing any error checking, so it's no surprise the query breaks silently when it fails. Check for errors and it will tell you what goes wrong - how to do it is outlined in the manual on mysql_query() or in this reference question.. Example:
$result = mysql_query($string);
// Bail out on error
if (!$result)
{
trigger_error("Database error: ".mysql_error(), E_USER_ERROR);
die();
}
In this specific case, I'm fairly sure it's because you are not putting your values into quotes after the VALUES keyword.
Also, the code you show is vulnerable to SQL injection. You need to escape every value you use like so:
$resID = mysql_real_escape_string($_REQUEST['resID']);
for this to work, you need to put every value in your query into quotes.
try this
$string = "INSERT INTO `materialen_per_reservatie`(`reservaties_id`) VALUES ('".$resID."')";

PHP/MySQL Check If Value Exists, If So-Do Not Insert It

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.

Categories