update table in mysql get strange results - php

I try to update an existing table in mysql, but I get strange results, I explain my problem:
My table looks like this:
TABLE `myTable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`photoName` varchar(255) COLLATE latin1_general_ci NOT NULL,
`vote` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `photoName_2` (`photoName`),
)
and im trying to use saveVote.php that look like this:
$namePhoto = $_POST['name'];
$likePhoto = $_POST['like'];
mysql_connect("host","dbUser","psw");
mysql_select_db("db_is");
mysql_query("INSERT INTO `myTable` (`photoName`,`vote`) VALUES('$namePhoto','$likePhoto') ON DUPLICATE KEY UPDATE vote = vote + 1");
the 'vote' value is updated but every time when i call the "saveVote.php", for the first time he create an empty entry in my table with only the vote value and after, each time the "saveVote.php" is called
the vote value is updated for the right photoName but the vote value for the empty entry is also updated.
Why my request created this empty entry ?
Thanks for help.

It seems like your $namePhoto = $_POST['name']; is also returning a empty value. Try this:
if(!empty($_POST['name'])){
mysql_query("INSERT INTO `myTable` (`photoName`,`vote`) VALUES('$namePhoto','$likePhoto') ON DUPLICATE KEY UPDATE vote = vote + 1");
}
Keep in mind that this is just to test. This is not a fix. You need to figure out why you are sending a empty value.

Related

Foreign Key Failure in MySQL

I have created a database composed of three tables. This is my query in creating my tables with Foreign Key.
CREATE TABLE reporter
(
reporterid INT NOT NULL AUTO_INCREMENT,
firstname VARCHAR(1000) NOT NULL,
lastname VARCHAR(100) NOT NULL,
PRIMARY KEY (reporterid)
);
CREATE TABLE flood
(
floodid INT NOT NULL AUTO_INCREMENT,
address VARCHAR(500) NOT NULL,
description VARCHAR(1000) NOT NULL,
dateofflood DATE NOT NULL,
timeofflood INT NOT NULL,
PRIMARY KEY (floodid)
);
CREATE TABLE reports
(
reportid INT NOT NULL AUTO_INCREMENT,
timereport NODATATYPE NOT NULL,
datereport DATE NOT NULL,
rid INT NOT NULL,
fid INT NOT NULL,
PRIMARY KEY (reportid),
FOREIGN KEY (rid) REFERENCES reporter(reporterid),
FOREIGN KEY (fid) REFERENCES flood(floodid)
);
I created a system in order for me to add records/row on my database through PHP. This is my code:
<?php
mysql_connect("localhost", "root", "") or die("Connection Failed");
mysql_select_db("flooddatabase")or die("Connection Failed");
$description = $_POST['description'];
$address = $_POST['address']; // Make sure to clean the
$dateofflood=$_POST['dateofflood'];
$timeofflood=$_POST['timeofflood'];
$firstname=$_POST['firstname'];
$lastname=$_POST['lastname'];
$dateofreport=$_POST['dateofreport'];
$timeofreport=$_POST['timeofreport'];
$query = "INSERT into flood(address,description,dateofflood,timeofflood) values ('$address','$description','$dateofflood','$timeofflood')";
$query2 = "INSERT into reporter(firstname,lastname) values ('$firstname','$lastname')";
$query3 = "INSERT into reports(dateofreport,timeofreport) values ('$dateofreport','$timeofreport')";
if(mysql_query($query))
if(mysql_query($query2))
if(mysql_query($query3))
{
echo "";
} else
{
echo "fail";
}
?>
The result that I am getting is fine. It's just that, in my REPORTS table, there is no foreign key that is being generated. For example I input something on my reporter table and flood table, the foreign key 'rid' and 'fid' has no values that references to both tables. Need help thank you.
Get the just inserted Primary key value from flood table insert
query. And store it to a variable say $f_id;
Get the just inserted primary key value from reporter table insert
query and store it to a variable say $r_id;
Now Make your last insert statement like below:
"INSERT into reports(dateofreport,timeofreport,rid,fid) values ('$dateofreport','$timeofreport',$r_id,$f_id)";
I am not giving you a direct copy paste solution.
If you need to know how to get the last inserted id by executing an insert query then look at this link
there is no foreign key that is being generated
I'm not entirely sure what you even mean by that. Foreign keys aren't "generated". Primary keys can be, which you do:
reporterid INT NOT NULL AUTO_INCREMENT
(as well as for your other two tables)
the foreign key 'rid' and 'fid' has no values
Well, look at your query:
INSERT into reports(dateofreport,timeofreport) values ...
Where do you insert values for rid and fid? I'm actually pretty surprised this query works at all, since those columns don't allow NULL values:
rid INT NOT NULL,
fid INT NOT NULL,
(Though your column names also don't line up, so I find it likely that the code you're showing isn't actually the code you're using...) That point aside however, the fact still remains that if you want a value in those fields then you have to put a value in those fields:
INSERT into reports(dateofreport,timeofreport,rid,fid) values ...
After each query, you can get the last generated identifier from mysql_insert_id():
$last_id = mysql_insert_id();
Use that to then populate the values being inserted as foreign keys in subsequent queries.
Also worth noting, the mysql_* libraries are long since deprecated and have been replaced with mysqli_ and other libraries such as PDO. I highly recommend you upgrade to a current technology, since what you're using isn't supported by any vendor.
Additionally, and this is very important, your code is wide open to SQL injection attacks. This basically means that you execute any code your users send you. You should treat user input as values, not as executable code. This is a good place to start reading on the subject, as is this.

MySQL INSERT IGNORE Adding 1 to Non-Indexed column

I'm building a small report in a PHP while loop.
The query I'm running inside the while() loop is this:
INSERT IGNORE INTO `tbl_reporting` SET datesubmitted = '2015-05-26', submissiontype = 'email', outcome = 0, totalcount = totalcount+1
I'm expecting the totalcount column to increment every time the query is run.
But the number stays at 1.
The UNIQUE index composes the first 3 columns.
Here's the Table Schema:
CREATE TABLE `tbl_reporting` (
`datesubmitted` date NOT NULL,
`submissiontype` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`outcome` tinyint(1) unsigned NOT NULL DEFAULT '0',
`totalcount` mediumint(5) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `datesubmitted` (`datesubmitted`,`submissiontype`,`outcome`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
When I modify the query into a regular UPDATE statement:
UPDATE `tbl_reporting` SET totalcount = totalcount+1 WHERE datesubmitted = '2015-05-26' AND submissiontype = 'email' AND outcome = 1
...it works.
Does INSERT IGNORE not allow adding numbers? Or is my original query malformed?
I'd like to use the INSERT IGNORE, otherwise I'll have to query for the original record first, then insert, then eventually update.
Think of what you're doing:
INSERT .... totalcount=totalcount+1
To calculate totalcount+1, the DB has to retrieve the current value of totalcount... which doesn't exist yet, because you're CREATING a new record, and there is NO existing data to retrieve the "old" value from.
e.g. you're trying eat your cake before you ever went to the store to buy the ingredients, let alone mix/bake them.

index uniq key does not seems to work

I'm trying to do a kind of friend request for my chat,
so I set a table called cyb_user_friendlist
then I've put some tables like that :
1 id_friendlist int(11) AUTO_INCREMENT
2 from int(11)
3 to int(11)
4 couple varchar(11)
5 accept int(11)
6 block int(11)
so for each friend request an insert is done to this table with id of sender into from and id of receiver into to, but to make sure that there is only one request per couple I added a field called couple in which there is the concatenation of from and to with a vertical separator |. this field has a uniq key because I want to prevent from multiple records.
the only thing is that it does not seems to work, actualy I added my uniq key to this fields and a primary key to the id_friendlist but it does not work, I can send many request as wanted...
my request $sql to do that is the one below :
$query = "INSERT INTO `cyb_users_friendlist` SET
`from` = {$from},
`to` = {$to},
`couple` = '{$from}|{$to}'";
I really do not know where I'm wrong...
anykind of help will be much appreciated.
$query = "INSERT INTO `cyb_users_friendlist` SET
`from` = $from,
`to` = $to,
`couple` = concat('$from','|','$to')'";
Why are you adding another field which is concatenated of two another when you can just add unique index?
mysql combined unique keys
ALTER TABLE `YOUR TABLE` ADD UNIQUE `unique` ( `from` , `to` )

How would I be able to duplicate my auto_increment? DATABASE PHP

Hey how would I be able to duplicate my only auto increment key to another key, basically I want my (' id ') to display the same information on my (' user_id '), here is the code:
CREATE TABLE IF NOT EXISTS `".$db_table_prefix."users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL,
`user_name` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`id`)
How would I be able to input the same information from my id to my user_id?
Not sure what you mean but if you want to have the same value repeted two times in the same record It's pointless and redundant.
You can use the SQL aliases to achive what you want:
SELECT id as user_id FROM ...
If you really need to sync up the two field of your table you can do:
UPDATE table SET user_id = id WHERE user_id != id
Not sure why you would want to do this, but if you want to duplicate the information after an INSERT you would need to fetch the new ID and then perform an UPDATE
// get the newly inserted ID
$new_id = $db->insert_id;
// perform the update on the table
$db->query("UPDATE users SET user_id=".$db->escape($new_id)." WHERE id=".$db->escape($new_id));
Also, in your table definition the fields don't match: int(11) vs. int(10).

How can I avoid creating duplicate rows?

Everything I have searched for and found has yet to work because I am accessing the Table through a php script and differently than everything I see. Anyways,
I am importing Feeds from a website into a mysql table. My table was created like this...
$query2 = <<<EOQ
CREATE TABLE IF NOT EXISTS `Entries` (
`feed_id` int(11) NOT NULL,
`item_title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_link` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_date` varchar(40) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
EOQ;
$result = $db_obj->query($query2);
I enter the data like so....
foreach($rss->channel->item as $Item){
$query5 = <<<EOQ
INSERT INTO Entries (feed_id, item_title, item_link, item_date)
VALUES ('$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;
$result = $db_obj->query($query5);
}
Now, every time Import new feeds from the site I want to make sure I delete any duplicates that might already be there. Everything I have tried, especially DISTINCT, has not worked for me. Does anyone know what type of query I could use to create a temp table, copy over any distinct rows (ENTIRE ROWS, if a title is the same but the date is different I want to keep that), drop the old table, then rename the tamp table to what I want.... or something similar?
Avoid using the duplicate rows in the first place. Make any unique values into keys. When adding new values to your database, use
REPLACE INTO Entries (feed_id, item_title, item_link, item_date)
VALUES ('$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;
The duplicates will be automatically overwritten. Replace is handy because it works like an insert when there is no conflict in the keys, but when there is then it will update the record and bump up any auto-incrementing keys.
EDIT
I've been drumming over this for a while. Here's what I came up with.
The problem with making a multi-column key on (feed_id, item_title, item_link, item_date) is that it will exceed the 1000 byte limitation in MySQL for key length. So instead alter your schema like so:
CREATE TABLE IF NOT EXISTS `Entries` (
`hash` varchar(32),
`feed_id` int(11) NOT NULL,
`item_title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_link` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`item_date` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (hash)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Now when you store a new value, get a hash of the values together:
$hash = md5($get_id . $Item->title . $Item->link . $Item->pubDate);
And for your insert statements use the following:
REPLACE INTO Entries (hash, feed_id, item_title, item_link, item_date)
VALUES ('$hash', '$get_id','$Item->title','$Item->link','$Item->pubDate')
EOQ;
The hash will be a unique representation of the record in it's entirety, and will be easy to compare in order to avoid duplicates. Now when you attempt to add the same record more than once, it will just replace the existing entry, and your query will not fail. As an alternative, you could continue to use insert, and the query will return an error, which you could handle however you want to.
The fastest and easiest way to delete duplicate records is by issuing a very simple command.
ALTER IGNORE TABLE [TABLENAME] ADD UNIQUE INDEX UNIQUE_INDEX ([FIELDNAME])
What this does is create a unique index on the field that you do not want to have any duplicates. The ignore syntax instructs MySQL to not stop and display an error when it hits a duplicate. This is much easier than dumping and reloading a table. It will also add unique indexes so that no new duplicates will be added. Just change you INSERT to INSERT IGNORE.
This also will work, but is not as elegant:
delete from [tablename] where fieldname in (select a.[fieldname] from
(select [fieldname] from [tablename] group by [fieldname] having count(*) > 1 ) a )
Perhaps do something like this:
$query2 = 'CREATE TABLE entries_new LIKE entries';
$result = $db_obj->query($query2);
$query5 = 'INSERT INTO entries_new (feed_id, item_title, item_link, item_date) VALUES ';
foreach($rss->channel->item as $Item){
$query5 .= '('$get_id','$Item->title','$Item->link','$Item->pubDate'),';
}
$query5 = rtrim($query5, ',');
$result = $db_obj->query($query5);
$query6 = "RENAME TABLE entries TO entries_backup, entries_new TO entries";
$result = $db_object->query($query6);
This will create a table called entries_new like your entries table. Make a single insert of data into entries_new and then rename the old table to entries_backup and the new table to entries.
You might also want to consider wrapping this whole sequence up in a transaction.

Categories