Duplicate entry mysql unique field - php

I have a 'code_number' column with varchar(25) field type, and I make it into Unique field type. I try to insert 2 number to the number column with different number. First number is '112225577' and for the second number is '112228899'. Now I'm trying to update the first number, and only change 3 last digit number '577' with '433', became '112225433'. But I got error Duplicate entry '112225433' for key 'code_number'.
How can it be duplicate? I only have 2 data and the data is not same. Can anybody explain to me why this happening?
UPDATE
here is my code.
Product
id INT(11)
product VARCHAR(250)
code_number VARCHAR(25) UNIQUE
...
Account
id INT(11)
name VARCHAR(250)
email VARCHAR(100) UNIQUE
...
And my query is like this:
$this->db->set('code_number','112225433');
$this->db->where('code_number','112225577');
$this->db->update('product');
Same problem goes to email column when i try to update account record.
here is the code sample:
$this->db->set('email','andy123#yahoo.com');
$this->db->where('name','Andy');
$this->db->update('account');
the email data in email column where name='Andy' is 'andy123#hotmail.com'.

You can definitely do this without a problem (see the SQL Fiddle here).
I imagine that you are doing something where both rows are getting updated to the same value, the equivalent of:
update t
set code_number = '112225433';
This will generate exactly the error you report. There are, no doubt, many SQL queries that would have this effect. But, this would generate such an error.

It could be a problem with your SQL editor. For instance, it could show you the previous value but it could have update it already, so that you you believe that it has not been changed yet. I ever had such problem like this before: the value was updated in the DB but the editor had no updated yet.

Related

MySQL: How can I allow a CHAR row to be duplicate?

So I made a basic database with a table named "logs". In logs, I made a column (let's say "ID").
Next, I coded some PHP (INSERT INTO logs (ID) VALUES ('$ID');) and went to test it. I used the same value 2 times, and I got an error: Duplicate entry.
I knew this would happen, but is it possible to allow 2 or more rows to be the same in a CHAR( 255 ) column?
Any help will be appreciated.
If you don't make a field as primary key, or unique you can place duplicates there. The same applies for your Char(255) column.
Fields are by default not primary keys, and not unique. So, unless you change it yourself, duplicates are allowed.

MySQL - Field 'id' doesn't have a default value

I can't insert any rows into my database, and the error I'm getting is:
This doesn't make any sense as it was working fine before, nothing has changed as far as I know. The ID field is set to primary, not null and auto increment:
I was able to insert a row manually through PHPMyAdmin. Heres the code I'm inserting with:
$query = "INSERT INTO wp_genomics_results (file_id,snp_id,genotype,reputation,zygosity) VALUES (?,?,?,?,?)";
$stmt = $ngdb->prepare($query);
$file_id = $this->fileID;
$snp_id = $row['id'];
$genotype = $this->formatGenotype($extractedGenotype);
$zygosity = $this->assignZygosity($genotype,$minor_allele);
$reputation = $this->assignReputation($zygosity,$genotypes);
$stmt->bind_param("sssss", $file_id,$snp_id,$genotype,$reputation,$zygosity);
$stmt->execute();
I tried deleting the table and creating a new table but it didn't fix it. Is there anything else I can do to try and diagnose and fix this?
make sure for this line:
$stmt->bind_param("sssss",
$file_id,$snp_id,$genotype,$reputation,$zygosity);
First parameter of bind_param() you used is "sssss" that means all off data is string. Please fix it as the right type data of your type on table database.
Please use "i" for integer. For example:
$stmt->bind_param("iisss",
$file_id,$snp_id,$genotype,$reputation,$zygosity);
I make the code above as an example because I can not see all of your table descibe.
I tried inserting with the WordPress database connection:
$wpdb->query("INSERT INTO wp_genomics_results (file_id,snp_id,genotype,reputation,zygosity) VALUES ('$file_id','$snp_id','$genotype','$reputation','$zygosity')");
and it works, but if I try using an identical query with my own database connection:
$db = new mysqli('localhost', NG_DB_USER, NG_DB_PASS, NG_DB_NAME);
$db->query("INSERT INTO wp_genomics_results (file_id,snp_id,genotype,reputation,zygosity) VALUES ('111','$snp_id','$genotype','$reputation','$zygosity')");
I get the same error:
Error No: 1364 - MySQL error Field 'id' doesn't have a default value
I don't understand why it works with wordpress but not my own database connection. I went into my mysql.ini file and changed this:
sql-mode="STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,
NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
to this:
sql-mode=""
and now I can insert a row, the error stopped happening. I still don't understand why this error was occuring to begin with. And now theres a new error happening:
Duplicate entry '0' for key 'PRIMARY'
I don't understand it because the id column is set to auto increment. Theres also no rows in there with ID = 0. I even emptied the table to make absolute sure there is no row in there with ID = 0. I'm very confused about whats happening. Heres the output of the table structure:
> mysql> SHOW CREATE TABLE wp_genomics_results;
| wp_genomics_results | CREATE TABLE `wp_genomics_results` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`file_id` int(11) NOT NULL,
`snp_id` int(11) NOT NULL,
`genotype` varchar(3) NOT NULL,
`reputation` varchar(3) NOT NULL,
`zygosity` int(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
I notice it says 1 row in set, but the table is actually empty. And once again, I'm able to insert a new row through PHPMyAdmin:
Oh God I feel like an idiot. All this time, the problem was that I had the wrong database selected. So it was querying a table from a different database, and this tables ID field didn't have auto increment set. Ah well, it was a good learning experience, getting to know MySQL better.
EDIT
The table definition looks really strange. It looks like there's a second index on the id column. The id column is already defined as the PRIMARY KEY.
It's this line in the table definition that is bothers me...
KEY `id` (`id`)
It's bizarre that MySQL would even let you add a second index on the same column, and not return an error like "such an index already exist" or "the set of columns is already indexed" or such.
I recommend you run a statement to drop the index named id. Execute either
DROP INDEX `id` ON `wp_genomics_results`;
-or-
ALTER TABLE `wp_genomics_results` DROP KEY `id`;
It's possible that this index was contributing to the issue.
ORIGINAL ANSWER
I suggest you figure out exactly which statement is throwing an error.
I suspect it's not the execution of INSERT INTO wp_genomics_results statement.
If it were me, I'd take a look at the assignZygosity and assignReputation functions. I suspect the culprit is in down in there.
I suspect there's something going on in those functions. My guess (just a guess) is that one of those functions is performing a lookup to get a value for a foreign key. And, if a foreign key value isn't found, something is being executed to INSERT a row into the referenced table. There must be some reason that function is being called, some reason we're not just using the value supplied as a parameter...
The formatGenotype function is also a suspect, by proximity. (I'm less a-feared of that function name... but again, I have no idea what that function is doing.)
If that's not the issue, if it's really the execution of the INSERT statement shown in the code, then I'd look for a "BEFORE INSERT" trigger on the wp_genomics_results table... maybe the trigger is performing an insert to some other table.
As a quick test, I'd comment out the calls to those functions, and just assign a literal values to $zygosity and $reputation.
I want to know the exact line number in the exact file where the error is being thrown.
I also want the complete error message from MySQL.
Following every execution of a database interaction, I want to check the return, and if there's an error, I want (for debugging purposes) a unique message that indicates where we are in the code when the error is thrown, along with the complete error message returned from MySQL (mysqli_error).
I'm not going to just assume, without evidence, that it's the execution of this particular statement that's causing the error.
And if it really is this statement, then we'd need to take a look at the actual MySQL definition of the table... the output from a SHOW CREATE TABLE wp_genomics_results statement.
And we want to make sure that we are looking at the same MySQL instance and database that the code is connecting to, and not some other MySQL instance or database.

How to allow a column variable to be changed only once with PHP/MySQL?

I have a table in my MySQL DB with information from each user that they submitted during registration.
I would now like to allow users to change one of those columns (Column X), but only once.
What is the best way to do that?
The only way I can think of is to add an additional column (Column Z) to the table with a binary value that defaults to 0, and changes to 1 when Column X is updated by the user. If Column Z is 0, the site allows the change, otherwise, it does not allow it.
Is there a better way? Should Column Z be in the same table as Column X? Any other relevant points/issues I should consider?
Thanks.
You could have a default value for column x that gets created once the row is inserted to the table. Then when the user wants to update his row, the db checks this value, if it has not changed since insertion, then the user can be allowed to update. Otherwise it rejects
CREATE TABLE example_table (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
data VARCHAR(100),
value_to_be_updated_once DEFAULT NULL
);
in your code you can check if the column (value_to_be_updated_once) is null, then the user should be allowed to edit.
You must make sure that the user does not set this value to NULL, unless that is something you want to have. (maybe the user changed his/her mind and will edit later)
You may, at some point, decide to allow the user to change columnX 3 times. A boolean will not allow for this. And what if you decide to allow the user to change columnY too. What then?
If you are absolutely positive that you will never need to change your rules, a binary flag will work fine. But if you will potentially be allowing and limiting changes on multiple columns with possibly different limits, you might consider a User_Edits table. It might look something like this:
tablename varchar(30) not null,
columnname varchar(30) not null,
user_id int unsigned not null,
changetime timestamp default current_timestamp,
oldvalue text
To find out how many edits a user had done:
SELECT COUNT(user_id) FROM User_Edits
WHERE tablename='Mytable' AND columnname='ColumnX';
And, as an added bonus, you'll have an audit trail that allows you to undo changes.

Is it possible to insert a row but only if a value does not already exist?

Is it possible to insert a row, but only if one of the values already in the table does not exist?
I'm creating a Tell A Friend with referral points for an ecommerce system, where I need to insert the friend's email into the database table, but only if it doesn't already exist in the table. This is because I don't want any more than 1 person getting the referral points once the new customer signs up and purchases something. Therefore I want only one email ever once in the table.
I'm using PHP 4 and MySql 4.1.
This works if you have a unique index or primary key on the column (EmailAddr in this example):
INSERT IGNORE INTO Table (EmailAddr) VALUES ('test#test.com')
Using this if a record with that email already exists (duplicate key violation) instead of an error, the statement just fails and nothing is inserted.
See the MySql docs for more information.
If the column is a primary key or a unique index:
INSERT INTO table (email) VALUES (email_address) ON DUPLICATE KEY UPDATE
email=email_address
Knowing my luck there's a better way of doing it though. AFAIK there's no equivalent of "ON DUPLICATE KEY DO NOTHING" in MySQL. I'm not sure about the email=email_Address bit, you could play about and see if it works without you having to specify an action. As someone states above though, if it has unique constraints on it nothing will happen anyway. And if you want all email addresses in a table to be unique there's no reason to specify it as unique in your column definition.
Most likely something like:
IF NOT EXISTS(SELECT * FROM myTable WHERE Email=#Email) THEN INSERT INTO blah blah
That can be rolled into one database query.
A slight modification/addition to naeblis's answer:
INSERT INTO table (email) VALUES (email_address)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)
This way you don't have to throw email=email_address in there and you get the correct value for LAST_INSERT_ID() if the statement updates.
Source: MySQL Docs: 12.2.5.3
MySQL offers REPLACE INTO 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.
I'm not sure if I got it, but what about a
try {
mysql_query($sql);
}
catch(Exception $e) {
}
combined with an unique field index in MySQL?
if it throws an exception then you know that you got a duplicated field.
Sorry if that don't answer your question..
If the email field was the primary key then the constraints on the table would stop a duplicate from being entered.

Auto increment stopped in MySQL?

I'm working on a script that sadly I inherited - with no commenting or anything. Argh!
For testing purposes I duplicated one of the tables in the database which had an auto-incrementing ID. When the data is saved to the database, though, the ID number just reads "0" -- which is the default for that column. I'm not sure why it's not auto increasing anymore... any thoughts? Thank you!
Are you sure you set the field in the duplicate table to auto-increment? Try running:
ALTER TABLE `duplicate_table` CHANGE `ai_key` `ai_key` INT( key_length ) NOT NULL AUTO_INCREMENT
And see if it is set or not.
Did you create the new table from scratch or as a real copy? If the column is supposed to auto increment it should be a primary (or at least a unique) key, with no default value.
Just to double check use the sql statement to show the show create table syntax for both tables and compare.
show create table <table>
It sounds like your column isn't actually auto_increment any more. This has happened to me a couple of times because there was a bug (?) in phpMyAdmin which I used to create backups: it wouldn't add the auto_increment keyword into the CREATE TABLE statements. That was a massive pain in the butt...

Categories