I have an Auto increment ID column in my table and it does work fine when I insert the records using PHP. I have to delete the records from this table every hour using the DELETE statement. I changed the PHP.ini file and restarted the machine. For some reason Auto increment ID started from '1' again. There were no records in the table when I restarted the machine. I am using PHP 5.3.8 and MySQL 5.5.21 running under IIS. Please let me know if there are any suggestions. Here is my table schema.
CREATE TABLE `test_table` (
`test_id` int(11) NOT NULL AUTO_INCREMENT,
`test_date` datetime DEFAULT NULL,
`test_location` varchar(2000) NOT NULL,
`test_summary` varchar(4000) NOT NULL,
`create_dtm` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`test_id`)
) ENGINE=InnoDB
Here is my insert query
$Sql = "INSERT INTO test_table(test_date, test_location, test_summary) VALUES ('" .sDate. "', '" .$location. "', '" .$summary. "')";
$Result = mysql_query($Sql) or die(mysql_error());
$new_id = MySql_Insert_Id();
Here is DELETE.
$Sql1 = "DELETE FROM test_table";
$Result1 = mysql_query($Sql1) or die(mysql_error());
Using a DELETE with no where clause is the same as TRUNCATING a table, hence they both reset the Next AutoIndex value for the table. (Which is what people would normally want / expect)
Could use something like the following to get around this in your case maybe:
mysql_query(
sprintf(
"ALTER TABLE tbl_name AUTO_INCREMENT = %d",
mysql_insert_id() + 1
) );
(If the DELETE clears the insert value then you will just need to cache it before your DELETE / TRUNCATE)
Related
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.
I am trying to make an SQL query that :
IF the $post_id exists then it updates the records,
IF NOT then then it creates the record
Here is my code
$vote_new_total = $vote_total + $vote;
$vote_count = $vote_count + 1;
$query = " INSERT INTO cute_review_vote (vote_total, vote_count)
VALUES ('$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
WHERE post_id = $post_id";
mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
However, I keep getting the following error:
Notice: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE post_id = 214748364' at line 4 in in C:\xampp\htdocs\xbm-vote\do_vote.php on line 68
Is this an issue with my syntax or am I missing something more obvious than that?
Any help/advice would be greatly appreciated. Thanks.
There is no where with ON DUPLICATE statement. Always check syntax: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
Also, that is not a secure query. Turn that into a prepared statement.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
EDIT: Updating answer since OP didn't understand usage of ON DUPLICATE statement:
ON DUPLICATE will consider that you're trying to insert a KEY value.
Consider the example table:
CREATE TABLE `user` (
`email` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`is_active` tinyint(4) NOT NULL,
`datecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`email`)
);
And the query:
INSERT INTO user (email, name, is_active) VALUES ("user#user.com", "User", 1)
ON DUPLICATE KEY UPDATE name = "User Edited", is_active = 0
Since we're setting PRIMARY KEY as email, and the insert statement is inserting a key, then, at the second time you run the query, ON DUPLICATE would run once a email is already on the table, because it is the KEY and you are trying to insert it again, but you defined a ON DUPLICATE KEY ....
If a table runs with a AUTO_INCREMENT column, is most likely you have to SELECT post_id applying some filter with WHERE statement.
Ok, I found my problem.
INSERT INTO cute_review_vote (post_id, vote_total, vote_count)
VALUES ('$post_id', '$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
I realized, thanks to Fabiano, that the WHERE clause is not required.
WHERE post_id = $post_id"
Is simply replaced by defining the database entry within the INSERT INTO command.
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.
I have an MySQL table named i_visited structured like: userid,tid,dateline
And I run this condition in view_thread.php page:
if (db('count','SELECT userid FROM i_visited
WHERE tid = '.intval($_GET['id']).'
AND userid = '.$user['id']))
mysql_query('UPDATE i_visited
SET dateline = unix_timestamp(now())
WHERE userid = '.$user['id'].'
AND tid = '.intval($_GET['id']));
else
mysql_query('INSERT INTO i_visited (userid,tid,dateline) VALUES
('.$user['id'].','.intval($_GET['id']).',unix_timestamp(now()))');
The problem is that it executes in 80/100 ms (on Windows) 40/60 (on Linux)
1 row affected. (query executed in 0.0707 sec)
The mysql_num_rows() aka db('count',sql) uses 2 / 3 ms, so the problem is at the update and the insert.
P.S. i_visited is an utf8_unicode_ci (InnoDB), has anyone seen this problem?
Other queries run normal (2 / 3 milliseconds)
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
KEY userid (userid,tid),
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
You do not need to do a select to check existence and then choose either Update or Insert.
You can use MySQL's ON DUPLICATE KEY UPDATE Feature like this.
$query = 'INSERT INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))
ON DUPLICATE KEY UPDATE
dateline = unix_timestamp(now())';
mysql_query($query);
This query will insert a new row if there is now KEY conflict, and in case a duplicate key is being inserted, it will instead execute the update part.
And as you have a KEY userid (userid,tid) in your CREATE Statement the above query is equivalent to your if...else block.
Try this and see if there are any gains
You can also use REPLACE INTO, as there are only the specified 3 columns, like this
$query = 'REPLACE INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))';
mysql_query($query);
But I would suggest looking at ON DUPLICATE KEY UPDATE as it is more flexible, as it can be used on a table with any number of columns, whereas REPLACE INTO would only work in some limited cases as other column values would also need to be filled in the REPLACE INTO statement unnecessarily
I think (part) of the problem is that your table does not have an explicit primary key.
You've only declared secondary keys.
Change the definition to:
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
PRIMARY KEY userid (userid,tid), <<----------
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
InnoDB does not work well without an explicit primary key defined.
I have a simple mysql DB and use this PHP code to update it.
mysql_query("REPLACE INTO `$db_table` (username, live, datetime, ip)
VALUES ('$username', '1', '$timeofentry', '$ip')");
I use REPLACE INTO along with a primary key on "username" to let users bump themselves to the top of the most recent list...
I would like to add a bump count. The number of times an entry has been updated (or "replaced into").
How would I go about doing this?
Thanks a lot!
You can use INSERT ... ON DUPLICATE KEY UPDATE which performs an actual update of existing rows.
$mysql = mysql_connect(..
...
$username = mysql_real_escape_string(...
$ip = mysql_real_escape_string(...
...
$query = "
INSERT INTO
`$db_table`
(username, live, datetime, ip)
VALUES
(
'$username',
'1',
'$timeofentry',
'$ip'
)
ON DUPLICATE KEY UPDATE
ip = '$ip',
bumpCount = bumpCount + 1
";
$result = mysql_query($query, $mysql);
First, you need to add another column to your table to keep the count.
Second, you should probably use the UPDATE statement instead of REPLACE.
REPLACE will actually delete the row, then INSERT a new one which isn't very efficient.
UPDATE `$db_table` SET datetime = NOW(), ip = '$IP',
bumpCount = bumpCount + 1 WHERE username = '$username' LIMIT 1;
#dot
You'd define your bumpCount field as another column in the table. I'd recommend setting it to a default value as well.
Then your table definition would be sometime like:
CREATE TABLE my_table
(username varchar(255) not null primary key,
live int,
datetime datetime not null,
ip varchar(15) not null,
bumpCount int unsigned not null default 1);
And your insert/update would be something like:
INSERT INTO my_table (username,live,datetime,ip)
VALUES
('$username',1,now(),'$ip')
ON DUPLICATE KEY UPDATE datetime=now() ip='$ip', bumpCount=bumpCount + 1;