How to avoid duplication of mysql table entries? - php

I seem to be getting duplicating table entries with using this PHP code. Every time I hit refresh, when it inserts what I have hard coded and prints previous entries (even if they values are the same).
What I want to know is how can I avoid duplication if the values are the same? I also do not want the code to duplicate entries when the page refreshes.
//insert data entries
mysqli_query ($con, "INSERT IGNORE INTO alarms(Title, Description, DT)
VALUES('get', 'Agha will eat', '2013-08-05 00:15:12')");
This is the print function.
//print out data entries
$result = mysqli_query($con,"SELECT * FROM alarms");
while ($row = mysqli_fetch_array($result))
{
echo $row['alarmID'] . " <br> " . $row['Title'] . " <br> " . $row['Description'] . " <br> " . $row['DT'];
}

Create a UNIQUE constraint in your alarm table based on the values which you want to be unique.
Suppose that for every row, you want the Title, Description and DT triples to be unique. Then, add the UNIQUE constraint in your alarm table in the following way -
ALTER TABLE alarm ADD CONSTRAINT uc_alarm UNIQUE (Title, Description, DT)
If you do this, then whenever you try to insert a row whose Title, Description and DT matches with those of an existing rows, MySQL will generate an error and reject that insert command.
Check out this short tutorial for a overview of the UNIQUE constraint.

Related

Maria DB SQL Insert INTO ON DUPLICATE working only for first updated value

I am using this http://www.phpzag.com/create-live-editable-table-with-jquery-php-and-mysql/ as a template for editing two columns in my table. The edited entries are saved in new SQL table and called by unique key identifier back.
With each edit where the ID does not exist in the SQL I need the ID to be created so instead just UPDATE:
UPDATE notes SET $update_field WHERE shop_order='" . $input["SHOP_ORDER_NO"] . "'"
statement in SQL I want to check if ID exist and if so, to just update edited value otherwise create ID and update value. The update statement above works when ID is created.
Code below update just the "priority" value, not the note when edited. Also when I edit "note" it will not create new ID. I tried to figure it out for half a day without success.
<?php
include_once("db_connect.php");
$input = filter_input_array(INPUT_POST);
$poznamka = $input['note'];
if ($input['action'] == 'edit') {
$update_field='';
if(isset($input["priority"])) {
$update_field.= "priority='".$input["priority"]."'";
} else if(isset($input["note"])) {
$update_field.= "note='".$input["note"]."'";
}
if($update_field && $input["SHOP_ORDER_NO"]) {
$sql_query = "INSERT INTO notes (shop_order,priority,note)
VALUES ('" . $input["SHOP_ORDER_NO"] . "','" . $input["priority"] . "','" . $input["note"] . "')
ON DUPLICATE KEY UPDATE $update_field ";
mysqli_query($conn, $sql_query) or die("database error:".mysqli_error($conn));
}
}
?>
That link is missing some things, like a PRIMARY KEY. And IODKU depends on a UNIQUE key, which is usually a different column.
Your statement will act on only row, assuming there is only one duplicate value for some UNIQUE key. Please provide SHOW CREATE TABLE and the generated SQL so we can point out specifics.
Read the online docs about using ... UPDATE id = LAST_INSERT_ID(id) as a kludge for getting the new or old auto_increment id.
If you need to apply IODKU to multiple rows, see the syntax
INSERT INTO t (col1, col2, ...)
ON DUPLICATE KEY UPDATE ...
SELECT ((multiple rows from somewhere else));
However, this cannot provide the auto_increment ids for each new/existing row.

php & mysql: Echo'ed table values cannot be re-inserted?

I have a table list of ingredients, which has about 5-6 values like cost, store, packaging, quanity, ect.
I then echo the data from the tables onto a drop down menu so they are selectable. However when I go to update or re-insert them into a new table, I get a error messaging saying "cost is not defaulted", even though it is.
So basically what is happening, is my drop down menu is NOT the database value itself when its time to use it to update it into a new table. Its stringified and its value is completely new. Is there a way to stop this from happening and tell mysql or PHP that I want the database values I originally put in when selected and not a stringified version of it?
<select name="ingredients_list" placeholder="Ingredients">
<option disabled selected value> -- select an ingredient -- </option>
<?php
$sql = "SELECT item, store
FROM ingredients
ORDER BY item";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($col = $result->fetch_assoc()) {
echo "<option>" . $col['item'] . " (" . $col['store'] . ") " . "</option>";
}
}
?>
Error Message:
Error: INSERT INTO meal_ingredients (meal_name, item) VALUES ('turkey', 'Bacon (Lidl)')
Field 'package' doesn't have a default value
It DOES have a value, but its not using it because its using the stringified "bacon" of the drop down, rather than the data on the database itself.
You are trying to insert only a part of the values for the table columns .. one of this column named package have a not null constrains so the partial insert
INSERT INTO meal_ingredients (meal_name, item) VALUES ('turkey', 'Bacon (Lidl)')
don't respect this constrain
could be you need
INSERT INTO meal_ingredients (meal_name, item,package )
VALUES ('turkey', 'Bacon (Lidl)', 'my_package_value')

how to work with array updates

I am looking for some inspiration from someone wiser than me with PHP/MySQL.
In have a database application, and in this instance there are two primary tables and one child table.
Primary Table 1 - Documents
Primary Table 2 - JobDesriptions
Child Table - LnkDocuments_JobDescriptions, which as the title suggests is a one to many relational table between the Document and Job Description Table. In my Documents Table I have a field which is a lookup of JobDescriptions and presents options as a checkbox, this field is called 'AppliesTo', because of the way the application works, the field stores the results as a string, eg "1,2,3,4,5) I have used the explode function to turn this into an array and then insert each record into the child table, as I prefer 1-2-many relationships. This is the code that I have, and it works.
$jdarray = explode(',',$values['AppliesTo']);
foreach($jdarray as $item)
{
$sql2 = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk)
values ('".$keys["DocumentPk"]."', '$item')"; CustomQuery($sql2);
}
The problem I now have is that if that table gets updated, I need to also update the child table, i have tried this code (but quickly realised that it is wrong):
$jdarray = explode(',',$values['AppliesTo']);
foreach($jdarray as $item)
{
$sql = "SELECT * FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk='$item'"; ;
$num_rows = mysql_num_rows(CustomQuery($sql));
if ($num_rows > 0) //Delete Record
{
$sql2 = "DELETE FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk='$item'"; CustomQuery($sql2);
echo "JD FK : ".$item." deleted";
}
else //Insert Record
{
$sql3 = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk)
values ('".$keys["DocumentPk"]."', '$item')"; CustomQuery($sql3);
echo "JD FK : ".$item." added";
}
}
It occured to me that I need to compare differences in the arrays, but havent got a clue how to do this, but this is what I need:
If I can get $oldarray and $new array to compare, for example
if in old array there were values 1,2,3,4 and in $newarray there were values 1,2,3,5, I want the code to loop through each value to determine if there is a change, e.g. if value exists in old and new array then do nothing, if value exists in old array but not new then delete, if value exists in new array but not old then insert.
I have also thought about just deleting all associated records and adding again, but think this is bad practice and will result in high number primary key, also it is worth noting that in my example there are only 5 options, this is just for testing, in reality there could be dozens.
Thanks in advance
If you are trying to optimize things I'm not sure that reading the values already present in the table and then deleting only those are not in the new version while inserting the missing records is the best way to go. In my opinion it would be much faster to just delete everything in one query, then insert all records in one query. Try something like this:
$item_list = implode( ',' , $jdarray );
$delete_query = "DELETE FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk IN ( $item_list )";
CustomQuery($delete_query);
$document_key = "'" . $keys["DocumentPk"] . "'";
$item_list_to_insert = "($document_key, " . implode( "), ($document_key, ", $jdarray ) . ")";
$insert_query = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk) VALUES " . $item_list_to_insert;
CustomQuery($insert_query);
Note: I didn't test this, there might some debugging needed.

OUTPUT clause get a return in PHP

After doing some research I think I need the Output clause. Essentially I am taking the below SQL and inserting into the specified table when I receive the location of a file I am uploading to the server. When I upload into the table the ID is an auto increment field and the primary key.
$conn = mysqli_connect($DBHOSTmy, $DBuser, $DBpass, $DBmy) or die("An error occurred connecting to the database " . mysqli_error($conn));
$query = "INSERT INTO ebwf (src,loc,iq,wq,pq) OUTPUT Inserted.id, Inserted.src, Inserted.loc, Inserted.iq, Inserted.wq, Inserted.pq VALUES ('" . $source . "','" . $finalPdf . "','y',0,0);";
echo $query;
$result = $conn->query($query);
echo $result->num_rows;
$conn->close();
When this runs I get a return of INSERT INTO ebwf (src,loc,iq,wq,pq) OUTPUT Inserted.src, Inserted.loc, Inserted.iq, Inserted.wq, Inserted.pq VALUES ('m','scan/WF_153_140812113520.pdf','y',0,0);, but I get no return of number rows.
I really just need the ID right this minute of the inserted row, but if we can get all of these fields that would be awesome.
I pretty much copied the usage of the OUTPUT clause from a few different places, but I don't see what I'm doing wrong to get no return...
I'm trying to do some research while writing this as I have not had good response rates because people think I'm lacking it so I also found: How do I use an INSERT statement's OUTPUT clause to get the identity value?... I changed my query only to:
$query = "DECLARE #OutputTbl TABLE (id INT, src VARCHAR, loc VARCHAR, iq INT, wq INT, pq INT);
INSERT INTO ebwf (src,loc,iq,wq,pq) OUTPUT Inserted.id, Inserted.src, Inserted.loc, Inserted.iq, Inserted.wq, Inserted.pq INTO #OutputTbl(id, src, loc, iq, wq, pq) VALUES ('" . $source . "','" . $finalPdf . "','y',0,0);";
I sadly still get nothing.. Hopefully this will give enough info as to what I should do next.
#cmorrissey provided a great solution...
$last_insert_id = $conn->insert_id;
This returns the last inserted id (I think primary key that is auto incremented is the most correct explanation.) This is better to use than OUTPUT. I'm not sure why OUTPUT is incorrect to use as I have seen it so many places and this only once from the user.

sql insert and update question

I have a form which to insert data into a database. This form takes the content of the fields, and then displays the result page showing the entered information in context. There is a link on this page to edit the user info, which go back to the previous form. Obviously, I do not want duplicate records inserted. Is there an easy way to use an update statement if a record already exists? I am doing this with ajax and php.
Take a look at:
INSERT ... ON DUPLICATE: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
REPLACE INTO: http://dev.mysql.com/doc/refman/5.0/en/replace.html
INSERT ... ON DUPLICATE will allow you to issue an UPDATE query when a UNIQUE INDEX or PRIMARY KEY is matched.
REPLACE works exactly the same, but if the row is found, the old row is deleted prior to inserting a new one. When using cascading deletes, this is especially something to take into account!
MySQL supports the addition of ON DUPLICATE KEY UPDATE to an INSERT statement, which should do what you want.
Assuming you have a field like 'username' or 'email', you could make use of that field to check if a record already exists, if it does, update it.
$res = mysql_query("SELECT primary_key FROM my_table WHERE `email` = '" . mysql_real_escape_string($email) . "'");
if($row = mysql_fetch_array($res))
{
// Record exists, update it
$q = "UPDATE my_table SET `username` = '" . mysql_real_escap_string($username) . "' WHERE primary_key = " . (int) $row['primary_key'];
}
else
{
// Record doesn't exist, insert
$q = "INSERT INTO my_table(username, email) VALUES('" . mysql_real_escape_string($username) . "', '" . mysql_real_escape_string($email) . "');";
}
In the above example I assume you have a primary key field that's an integer (primary_key).
You should consider using an ORM like http://www.ezpdo.net/blog/?p=2
Plain SQL in web applications should only be used if absolutely neccessary, alone for security reason, but also to avoid problems like yours.

Categories