0

Using phpMyAdmin and MySQL v5.5.49 consider:

CREATE TABLE op_sys (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    version VARCHAR(255) NOT NULL,
    -- UNIQUE KEY name_version (name, version)
    -- CONSTRAINT name_version UNIQUE (name, version)
    -- UNIQUE(name, version)
    -- CONSTRAINT UNIQUE(name, version)
)ENGINE=InnoDB;

I've tried all four of the commented out attempts to simply stop INSERT INTO sys_op duplicate values for "name" and "version". All four are processed without error.

The insert into:

INSERT INTO op_sys(name, version)
VALUES ('ANDROID','ANDROID');

executes "successfully". ANDROID ANDROID is now a row. Where have I gone wrong or what step am I not aware of? I've checked the MySQL manual and several different posts here that seem to say I'm doing it correctly... Thanks.

2 Answers 2

2

You seem to misunderstand what UNIQUE KEY means:

A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. For all engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL.

If your table has UNIQUE(name, version), then you can do:

INSERT INTO op_sys(name, version) VALUES ('ANDROID','ANDROID');

But, the next time you do it, it will fail because the table already holds a record with the same pair(name, version) as in the record you want to insert.

To prevent inserting a record that has the same value for name and version`, you could use a trigger:

CREATE TRIGGER different_values BEFORE INSERT ON op_sys
FOR EACH ROW BEGIN
 DECLARE identical_values CONDITION FOR SQLSTATE '45000';
 IF NEW.name = NEW.version THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Identical values for name and version';
 END IF;
END;

It will run before each INSERT on table sys_op, and if the name and version fields hold identical values, it will generate an error and the insertion will fail.

The error returned looks like this:

ERROR 1644 (45000): Identical values for name and version

Documentation:
- CREATE INDEX
- CREATE TRIGGER
- SIGNAL

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that's exactly what I was looking for. Cheers!
2

A multi-column unique index prevents you to have the same 2 values for these 2 fields between records. This means, you cannot have 2 records, where name and version are 'ANDROID','ANDROID'. However, a unique index does not prevent these fields from having the same value within a single row.

You either have to implement this control in application level, where you check if the 2 field values are the same and if yes, then do not do the insertion.

In the database layer you could ad a before insert trigger and check the 2 fields' value there and raise a custom error message using the signal command.

But I have such a de ja vu feeling. As if you had asked this question before and you could not do an if() in php...

1 Comment

No, first time. Yes, easy on the php side - just check if the value is in the column prior to executing the insert. I'll explore triggers, as this seems to be what I'm missing. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.