Find if incoming data exists in sql table - php

I have a form where the user is supposed to input data (name, streetname, streetnumber) and then i want to check if that data exists in the table (name, streetname+streetnumber) so i can use that row instead of making a new one.
Is there an easy way to do this or will i have to fetch the data into an array and search that somehow?
I have this code:
$sql = "INSERT INTO 725G54_proj_address VALUES (NULL,'$streetname','$streetnumber')";
$result1 = mysql_query($sql,$con);
$address=mysql_insert_id();
echo "ID of last inserted record is: " . $address;
echo "<br>";
$sql = "INSERT INTO 725G54_proj_contact VALUES ('Null','$name','$telephonenumber')";
$result2 = mysql_query($sql,$con);
$contact = mysql_insert_id();
echo "ID of last inserted record is: " . $contact;
$sql = "INSERT INTO 725G54_proj_LivesAt VALUES ('$contact','$address')";
$result3 = mysql_query($sql,$con);`enter code here`
What i would like to is is find out if example Mainstreet 31 allready exists in proj_address and if it does, use its autoincremented id for the insert into proj_Lives_at.
Edit:
I decided to go with sending queries to check if the data existed.
I load that into a variable and check if it is empty, but there is some problem so that "if(empty)" doesn't work as it should. the other way around ("if(!empty)") works however.
the query and loading look like this:
$sql2="SELECT 725G54_proj_address.Address_ID, GROUP_CONCAT( cast( concat( 725G54_proj_address.Street_Name, ' ', 725G54_proj_address.Street_Number ) AS char ) SEPARATOR ', ') AS addresses
FROM 725G54_proj_address
WHERE 725G54_proj_address.Street_Name = '$streetname' AND 725G54_proj_address.Street_Number= '$streetnumber'
GROUP BY 725G54_proj_address.Address_ID
ORDER BY 725G54_proj_address.Address_ID ASC";
$result2=mysql_query($sql2);
Edit 2:
I have tried switching to using count() instead of empty() and it found the variable as populated even when it shouldnt.

It sounds like you are creating a many-to-one relationship (potentially) and should therefore be storing that data in a separate lookup table. What I suggest in that case is to first try to insert that row using an "INSERT IGNORE" statement
(http://dev.mysql.com/doc/refman/5.5/en/insert.html) and then use mysql_affected_rows() to see if it made a change. If it didn't then you know there's a duplicate row, which you can select, take the ID of, and then you're done.
As somebody mentioned in one of the comments above, you can make that into a stored process.

Assuming you've created proper keys on your table (i.e., a unique key across (name, streetname, streetnumber), or something similar), then MySQL INSERT...ON DUPLICATE KEY UPDATE, or possibly REPLACE INTO, might be useful here. The former will convert your INSERT statement into an UPDATE if the key to be inserted already exists in the table, and the latter will act as regular INSERT unless the key already exists, in which case it will first DELETE the existing row before INSERTing the new data.
Of course, it's not exactly an onerous burden simply to SELECT COUNT(*) AS n_existing FROM table WHERE..., and then inspect n_existing in the result set to see whether a row already exists with the same key you're preparing to INSERT, and there is an argument to be made from the principle of least astonishment that it would be better to SELECT before INSERTing than to use abstruse SQL statements which may not have been encountered before by anyone else who's going to be maintaining your code. Still, the option exists, should you prefer it.

Related

Mysql only update if row has been inserted before

I want to only run the update query if row exists (and was inserted). I tried several different things but this could be a problem with how I am looping this. The insert which works ok and creates the record and the update should take the existing value and add it each time (10 exists + 15 added, 25 exists + 15 added, 40 exists... I tried this in the loop but it ran for every item in a list and was a huge number each time. Also the page is run each time when a link is clicked so user exits and comes back
while($store = $SQL->fetch_array($res_sh))
{
$pm_row = $SQL->query("SELECT * FROM `wishlist` WHERE shopping_id='".$store['id']."'");
$myprice = $store['shprice'];
$sql1 = "insert into posted (uid,price) Select '$uid','$myprice'
FROM posted WHERE NOT EXISTS (select * from `posted` WHERE `uid` = '$namearray[id]') LIMIT 1";
$query = mysqli_query($connection,$sql1);
}
$sql2 = "UPDATE posted SET `price` = price + '$myprice', WHERE shopping_id='".$_GET['id']."'";
$query = mysqli_query($connection,$sql2);
Utilizing mysqli_affected_rows on the insert query, verifying that it managed to insert, you can create a conditional for the update query.
However, if you're running an update immediately after an insert, one is led to believe it could be accomplished in the same go. In this case, with no context, you could just multiply $myprice by 2 before inserting - you may look into if you can avoid doing this.
Additionally, but somewhat more complex, you could utilize SQL Transactions for this, and make sure you are exactly referencing the row you would want to update. If the insert failed, your update would not happen.
Granted, if you referenced the inserted row perfectly for your update then the update will not happen anyway. For example, having a primary, auto-increment key on these rows, use mysqli_insert_id to get the last inserted ID, and updating the row with that ID. But then this methodology can break in a high volume system, or just a random race event, which leads us right back to single queries or transaction utilization.

Database check for uniqueness of two columns (and output of error message in PHP if it doesn't satisfy)

I'm trying to make a database check in my webpage that will check to make sure two columns (first_name and last_name) are unique. In MySql I already have those two columns as UNIQUE.
I want to have this check performed on the webpage, and return an error message if a first_name and last_name are already listed in the table. ex. If Tom Jones is in the table already, an error will show up if Tom Jones is input into the form. My statement below checks for this uniqueness, but it checks across all rows in the table. I need it to check row by row. member_no is the primary key, and I thought about searching with this, however, I want to check each row for uniqueness and I don't have a specific number to search.
This is just on the website/form side, since the UNIQUE statement for first_name and last_name is already active on MySql.
Or is there a more direct way to check the uniqueness in the table?
This is my statement:
$command = "SELECT * FROM member_info";
$member_result = mysql_query($command);
$mdata = mysql_fetch_object($member_result);
if ($first_name == $mdata->first_name && $last_name == $mdata->last_name) {
$error_message = "The first and last names must be unique. ";
}
This will check the table but will not discriminate between the rows. ex. if row 1 is Tom Jones, and row 2 is Bob Smith, and if I put into the form 'Tom Smith' the error will come back as not unique.
If first_name and last_name are in a multiple-column UNIQUE index then you can just go ahead and insert values. If the INSERTed values are already in the database then you will get an error saying so, and then you can take it from there.
To create a multiple-column UNIQUE index you can ALTER the table like so:
ALTER TABLE `member_info` ADD UNIQUE (`first_name`, `last_name`);
And then INSERT stuff like this:
$sql = "INSERT INTO `member_info` (`first_name`, `last_name`) VALUES ('{$first_name}', '{$last_name}')";
You should first make sure $first_name and $last_name are safe, though. If they are not then you will have security holes.
You can use a where-clause:
select * from member_info where first_name = {$first_name} and last_name = {$last_name}
You can optimistically try to insert and then react reasonably to the duplicate-key-message.
First mysql_ function are dprecated. Use mysqli.
First you want to clean the users input. I'll assume from this point that $first_name and $last_name are cleaned variables ready for use in a MySQl statement.
$query = "SELECT COUNT(*) FROM `member_info` WHERE `first_name`='$first_name' AND last_name='$last_name'";
$member_result = mysqli_query($command);
$mdata = mysqli_fetch_assoc($member_result);
if($mdata['COUNT(*)'] > 0) {
//user with that first and last name already exists
}
For keeping track of unique string values, I believe the most generic solution (but may be overkill for some cases) is to maintain another column with the hash of the string value and adding a UNIQUE constraint to that column. The overhead comes when modifying record data; you should also update the hash value (could be accomplished automatically with the use of triggers).
Bear in mind that indexes on character columns have a byte limit (problem & solution also referred in this question ). For short strings though, you could use the composite index solution as proposed by #sverri .

Can I add a new row to a table if a checkbox is checked using one query rather than nested? PHP, MySQL

After much head-scratching, I've got this query working - but it looks clunky and feels slow when it runs.
I have a table called UserTable which has a field called 'Item' populated if the specific user says 'yes' to that item. I only want to add a row for that item into UserTable in that instance - in other words, I don't want to have lots of user_ID/Item/'no' relationships in the table, only the user_ID/Item/'yes' responses.
I've built some code which shows the user the whole dataset and allows them to change their preference and then press update. When they update, an array called $checkbox is output which includes the item numbers (eg "1","3","6") which they've ticked as 'yes'. If they don't tick anything, $checkbox is set to "".
Here's the relevant code - as I say, it's very clunky, with a WHILE inside a FOREACH as well as two validating IF statements. Can I get rid of one (or both!) of the loops and replace with a SELECT type command?
foreach($checkbox as $value)
{if($value!="") {
$sql= "SELECT count(Item) as row_exists
FROM UserTable
WHERE Item = '$value' and
User_ID = '$current_user_id'";
$result = mysqli_query($mysqli,$sql) or die(mysqli_error($mysqli));
while ($iteminfo = mysqli_fetch_array($result)) {
If ((int)$iteminfo['row_exists']==0) {
$sql = "INSERT INTO UserTable
(User_ID,Item,Date) VALUES
('$current_user_id','$value',now() )";
$add_new_row = mysqli_query($mysqli,$sql) or die(mysqli_error($mysqli));
}
}
}
}
Many thanks in advance.
You can eliminate both if statements:
Filter your checkbox array on != "" and loop over those results. That gets rid of the first if that checks for != "".
Augment your initial query to include row_exists = 0, and iterate over those results. That gets rid of the second if.
In fact, you could probably merge your two sql statements into one composite conditional insertion. You are allowed to do insertions of the form:
INSERT INTO table (SELECT ...)
So you could look at taking your first query and adapting/substituting it for the SELECT... part of the query above, and taking your second insertion and adapting/substituting it in place of the INSERT INTO... above.
So if one user can be associated with multiple items, it seems that you should normalize this and have probably three tables - one for users, one for items, and one many-to-many table relating users to items.

Count SQL table row and add 1 on the outcome

I'm trying to count a table row and add 1 on the outcome, I have this snippet of code.
$countQuery = "SELECT COUNT(id) FROM donations";
$outcomeQuery = mysql_query($countQuery);
$countUp = mysql_fetch_array($outcomeQuery);
$plusOne = 1;
$outcome = $countUp;
echo $outcome[0]
or die(mysql_error());
But this gives me the error:
Fatal error: Unsupported operand types
I need this so I always have a unique number that's not used by a previous donator.
You could use:
SELECT COUNT(id)+1 as IDCount FROM donations
as your query instead. This will save you any mucking about in PHP to do the math. The array you pull back will have the number that you want right off the bat.
Edit: The better alternative however is to use a column type that increments automatically. In MySQL, this is done with the syntax auto_increment in the create table syntax.
Using this, you never actually have to insert a value, but rather, you pass it a NULL as follows (assuming that ID is the field with Auto_increment on it:
insert into tableName (ID,Name) values (null, 'Fluffeh');
So you see you don't give it any values for the ID column - the database takes care of using the right number.
use simple php
$countQuery = mysql_query("SELECT id FROM donations");
$count=mysql_num_rows($countQuery);
$count+=1;
It's dangerous to rely on COUNT to give you a unique number. What happens if two processes execute this query, and then both try and commit: you suddenly have the same value twice.
It would be much safer to implement some kind of sequence function independent of your table contents. This link shows one possibility:
http://forums.mysql.com/read.php?61,143867,238482#msg-238482
This question is for a MySQL database. I suggest you use the AUTO INCREMENT field type.
As you are using PHP, if you need to know the id after inserting a record, use:
mysql_query("INSERT INTO mytable (1, 2, 3, 'blah')");
$id = mysql_insert_id();
See mysql_insert_id().
Using
4 random generated numbers to make 100% sure there are no duplicates
will not make 100% sure there are no duplicates. Don't re-invent the wheel. This is how the problem of ensuring unique incrementing identifiers are used has been solved, you don't need the embarrassment of a homebrew solution that doesn't always work.

Php MySQL query where array value is not found

I have an array of data that generates unique data on the fly in a manor of speaking. It's actually an array with 5 hashes.
What I want to do is a basic select query with a where clause that checks each via OR basically a one line query rather than a query for each array item.
I'm attempting to ensure that no one hash that enters the db is the same as another which I know the probability is virtually null to that actually happening but it's a possibility none the less, safer than sorry is my perspective on the matter
Anyway the query I'm thinking of makes no sense as if a match is found the query will result in such what I wanna do is from the original array find the one that's not found and use it where if all 5 aren't found I'll just randomly pick one I guess in the end I want to form a result that is 1 to 5 in a new array so I can randomly pick from that result
Is this possible or would it just be easie to cycle over each one with a songle query?
"SELECT
CASE hashes.hash
WHEN $hashes[0] THEN 0
WHEN $hashes[1] THEN 1
WHEN $hashes[2] THEN 2
WHEN $hashes[3] THEN 3
...
END
FROM hashes WHERE hashes.hash IN(".implode($hashes).")"
This should tell you exactly which of the hashes you sent to the server have been found on the server.
The result set would be the index keys (0, 1, 2, 3) of the array that generated the query.
If you sent a query based on an array of 100 hashes and you get a result set of 99 hashes, that means at least one hash was not found in the db.
You could cycle through the result set like this:
while($row = $pdo->fetch()) {
$index = $row[0] // first column of the result set
unset($hashes[$index]);
}
When while finishes the only hashes left in the array should be the ones that weren't found in the database.
My opinion is that it would be easier to to cycle over each one with a single query. From what you say there appears to be no major benefit in doing it all at once.
In that case I would suggest:
alter table myTable create id_bkp int;
update myTable set id_bkp=account_id;
update myTable set account_id=56 where id_bkp=100;
update myTable set account_id=54 where id_bkp=56;
alter table myTable drop id_bkp;
Of course that will depend on what DB system you are using.
Do you mean something like this?
$sql = "SELECT * FROM `table` WHERE `field` = ";
$where_string = "'" . implode("' OR `field` = '",$my_array) . "'";
$sql .= $where_string;
You could use:
$my_array = array_unique($my_array);
To remove duplicate values.

Categories