alter table: only allow either unique or empty [duplicate] - mysql

This question already has answers here:
Unique constraint that allows empty values in MySQL
(3 answers)
Closed 9 years ago.
I have an existing mysql table, and I want to set one field (varchar) so that it must either be unique, or empty (by default). So when user does not enter value, its empty, otherwise user must enter unique value.
how would I do that ?

MySQL includes a constraint type UNIQUE that allows for exactly this. If you declare a column UNIQUE and allow NULL values in it, then all values will be forced to be unique unless they are NULL values. If you want to prevent empty strings ('') from being stored, you will have to manage that at the code level, because MySQL will treat it as just another string and allow it once in a UNIQUE column. If no value is passed to such a column, it will automatically default to NULL, but you can also specify NULL (not in quotes) programmatically in your code before passing the values to the database.
For the rest of this post I will assume the name of the table is tablename and the name of the column is columnname and the size of the varchar field is 255
If you want to modify an existing table, rather than create a new one:
If the column does not already support null values:
ALTER TABLE tablename ALTER COLUMN columnname VARCHAR(255) NULL
To add the unique constraint:
ALTER TABLE tablename ADD CONSTRAINT un_tablename_column UNIQUE (columnname)`
(I always name my constraints so I can refer to them specifically later)
OR if you want to do it on a new table:
CREATE TABLE tablename (
[...]
columnname varchar(255) UNIQUE NULL,
[...]
)

From what I have read, by standard it should not be possible to have a column in a table that allowes null values AND has a unique constraint; if it is, it is down to a special mysql-engine (that will result in unpredictable/unexpected behavior elsewhere also imho)
Also your question seems kind of reverse of this one
MySQL: UNIQUE, but DEFAULT NULL - allowed by creating of table. More than 1 NULL is allowed to insert. Why?
You could however enforce this using triggers, you can write a trigger on insert/update to check if the value already exists and immediatly delete it if it does.

I think you better process your data before pass to mysql, or not, you can write a trigger trigger whenever your table is update to make sure it pass your rule

Related

How to add Identity column into existing table in SQL? [duplicate]

I have an old MS Access DB which I'm translating to a MySQL DB. I used bullzip to create the database but due to bad design the old MS Access database didn't have a unique primary key for most of the tables.
So I've created a id field but obviously it's empty for each entry, I wonder if there's a simple statement I can use to fill them up with 1, 2, 3, 4 etc...
EDIT:
I think I haven't gotten my question across properly. I know all about auto increment. Thats not the problem.
I have a table, full of records which I need kept and which came from a Access database that didn't have a unique id defined as a field. In otherwords I have fields for firstname, surname etc etc but no field 'id'. This seems absolutely crazy but apparently this database has been well used and never had any unique ids for any tables bar one. Weird!
Anyway, I've created a field in the table for id (and set it to auto increment of course) but obviously all the existing records don't have an id set currently. So I need to create one for each record.
Is there a way to fill all these records with unique numbers using a mysql statement?
Cheers
If you add an new id column to an existing table and make it AUTO_INCREMENT PRIMARY KEY, it will automatically populate it with incrementing values.
mysql> ALTER TABLE TheTable ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY;
mysql> SELECT id FROM TheTable;
-- outputs values 1, 2, 3, etc.
If you made an id column but didn't declare it AUTO_INCREMENT PRIMARY KEY, you can populate the column like this:
mysql> SET #id := 0;
mysql> UPDATE TheTable SET id = (#id := #id+1);
Use a predefined AUTO_INCREMENT field, and set the value as NULL when inserting new records, so that it automatically builds up an appropriate incrementer. Aside from that, there is no way (unless using a procedure) to create an incrementing set of values
Use the auto_increment feature of MySQL. MySQL will generate unique numbers for your id column.
For an explanation of the auto_increment feature see http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
If you just want a unique identifier, you can use the uuid() function. It takes up a bit more space than an integer, but it does what you want.
However, I agree with the other answers that you should add an auto increment column and repopulate the table. That is the simplest way to keep the ids unique over time, even as updates takes place, and using a more reasonable amount of storage.
I am not proficient in MySQL, but I have faced this same problem in other DBMS's and here is how I have addressed it when there was an AutoIncrement type facility, but the DBMS had no way to automatically apply it retroactively:
Rename the table you want to add the ID field to. So rename Table1 to Table1_Old.
Create a new Table1 that is a copy of Table1_Old except that it has no data in it.
Add your ID/AutoIncrement column to Table1
Now copy all of the data from Table1_Old to Table1, either skipping or specifying NULL for the ID column. (This is usually a single INSERT..SELECT.. command)
Drop Table1_Old.
The actual specifics and commands vary from DBMS to DBMS, but I have usually been able to find a way to do these steps.
Use AUTO_INCREMENT
CREATE TABLE insect
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name VARCHAR(30) NOT NULL,
date DATE NOT NULL,
origin VARCHAR(30) NOT NULL
);
Update
I believe, it seems tough task unless you won't create new table, I will suggest you to use this
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, itemID FROM orders;
It will create a virtual column with the name rank for you, which have unique id value.

Insert row into MySQL table with default column value derived from other value

Given the following example table, I would like the default value of str_field_hash to contain the SHA1 hash of the value of str_field.
CREATE TABLE test (
str_field VARCHAR(1024) NOT NULL,
str_field_hash CHAR(40) NOT NULL,
CONSTRAINT str_field_hash_unique UNIQUE (str_field_hash)
);
str_field is too large for a unique key constraint.
This question contains answers indicating the newer versions of MySQL/MariaDB support using functions in default column values, though I've been unable to find information on whether I can derive a default value for a column from the value provided for another column.
I know I can use a trigger for this, but I'd love to keep it all confined to the table schema itself if possible.
Developing using MySQL v8.0.11.

MYSQL table column contraint based upon another tables columns

This is my first post and I'm a mysql noob, so I apologize for this question's length.
BACKGROUND
I have a lookup table cctypevals, with a foreign field 'cctypeID', in mysql this would be:
CREATE TABLE `cctypevals` (
`cctypevalsKEY` integer NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`cctypeID` varchar(50) NOT NULL, FOREIGN KEY(cctypeID) REFERENCES cctype(cctypeID) ,
`value` varchar(50) )
cctypeID contains field names from user tables, eg 'taskSTATE', 'serviceTYPE', 'projectCAT' etc.
The value field contains the only allowed values for these user table fields.
Thus cctypevals acts like a 'multi' keyed lookup table, for example:
select value from cctypevals where cctypeID ='serviceTYPE'
might return HomeVisit, BackToBase etc
I know it would be easier to have one lookup table per field but this is what I have.
QUESTION
How do I constrain (in a sql create table or alter statement), tables with fields like task.taskSTATE, service.serviceTYPE etc so they can only accept values from cctypevals.value where cctypeID contains the appropriate field name ?
In create or alter table statement you cannot do that, since the check constraint would be able to such things, but mysql has not implemented the check constraint yet (mysql can parse a check constraint, but it will not work).
You can create before insert and update triggers that check the specific restrictions and raise an sql error message if the updated value does not meet the requirements.

How to alter the table that can accept not null values

Can you please tell How to alter the table so that it can accept the not null constraint
alter table customer add emp_id int not null foreign key references emp(emp_id)
I have tried as above, but it is showing error:
Msg 4901, Level 16, State 1, Line 1
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column,
or alternatively if none of the previous conditions are satisfied the table must be
empty to allow addition of this column. Column 'emp_id1' cannot be added to non-empty table 'customer' because it does not satisfy these conditions.
The error is pretty clear.
You are trying to add a non-null column to a table that has data. When you add the column, it has no value. So, the default value is put into the table for the existing rows. There is no default value, so NULL is used.
You can solve this in a few ways. One would be to empty the table truncate table customer, add the new column, then load the data again.
Another way would be to add the column with NULL allowed. Then fill in the value everywhere and then add the NOT NULL constraint.

How to restrict Blank values in Primary Key column

I have a database of sql server 2008 which I am using to display in a gridview. I have written some code to add new rows in asp.net and C# as Code behind.
When ever a row is added through the Programming I have put some checking which will not allow the required values to be Null.
But, here comes my problem when ever any one of the user adds a new row manually by opening the Database, then a blank value is allowing in the Primary key column which is not 'Null value'.
So, here I have to restrict even not to allow blank values in primary key column, how can I solve this problem.
You need a check constraint
ALTER TABLE [TableName]
ADD CONSTRAINT [CK_PrimaryKeyNotEmpty]
CHECK
(
LEN([ColumnName]) > 0
)
I'm having trouble figuring out what you actual question is.
1) If you need to make a column not accept null values:
Add a constraint to the column in the db:
ALTER TABLE [Table] ALTER COLUMN [Column] INTEGER NOT NULL
See: Altering a column: null to not null
2) If you need to restrict your PK column to only certain values add a constraint:
ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
Column >= 0
)