How do I drop 'NOT NULL' from a column in MySQL? - mysql

A show create table command shows the following:
'columnA' varchar(6) NOT NULL DEFAULT '';
How do I modify that column so that the not null is removed?
I need it to be:
'columnA' varchar(6) DEFAULT NULL;
I thought the following would work, but it has no effect:
ALTER TABLE tbl_name MODIFY columnA varchar(6) DEFAULT NULL;

Try this instead:
ALTER TABLE tbl_name MODIFY columnA varchar(6) NULL DEFAULT NULL;

Normally, Eric's answer should work:
ALTER TABLE tbl_name MODIFY columnA varchar(6) NULL DEFAULT NULL;
(Although the 'NULL DEFAULT NULL' part is optional).
But like you, I had a case that just returned OK without doing anything. In my case it appears to be due to the fact that my key was part of the primary key. So I had to do the following:
ALTER TABLE tbl_name DROP PRIMARY KEY;
ALTER TABLE tbl_name MODIFY columnA varchar(6);
ALTER TABLE tbl_name ADD PRIMARY KEY (columnA);
with that last query specifying whatever your primary key actually is.
Also, in case anyone thinks that is too verbose, the following combined query does NOT work, even though it should be identical:
ALTER TABLE tbl_name DROP PRIMARY KEY, MODIFY columnA varchar(6), ADD PRIMARY KEY (columnA);
I assume that mysql rewrites that last query into a different order so that the primary key still exists when the modify is performed, hence the need to break it out into three statements.
FYI, this is on mysql 5.1.47 but I haven't yet found any documentation indicating why this happens so I don't know what versions are affected.

Make the change (locally) in phpMyAdmin. It will show the query it used for the change. Execute this query in production and you're done.
You can use this strategy in any GUI tool to see the queries it performs. I personally use Sequel Pro (for Mac OS X) instead of phpMyAdmin.

Related

How to DROP COLUMN with ALGORITHM=INSTANT

AS described in the MySQL documentation here, it should be possible to drop a column instantly with a syntax like this one:
ALTER TABLE tbl_name DROP COLUMN column_name, ALGORITHM=INSTANT;
It is documented that it is only possible with the following constraints:
Dropping a column cannot be combined in the same statement with other ALTER TABLE actions that do not support ALGORITHM=INSTANT.
Columns cannot be dropped from tables that use ROW_FORMAT=COMPRESSED, tables with a FULLTEXT index, tables that reside in the data dictionary tablespace, or temporary tables. Temporary tables only support ALGORITHM=COPY.
Unfortunately, I am unable to use the syntax described above. For example, here is my test code:
CREATE TABLE MyTable (
MyPrimaryKey bigint NOT NULL AUTO_INCREMENT,
UserId char(36) NOT NULL,
Username varchar(254) NOT NULL,
PRIMARY KEY (MyPrimaryKey),
UNIQUE KEY IX_UserId (UserId)
) ENGINE=InnoDB;
ALTER TABLE MyTable DROP COLUMN Username, ALGORITHM=INSTANT;
When I run this against MySQL 8.0.28, I get the following error:
Error Code: 1845. ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.
Am I doing something wrong or the documentation is missing something?
Note that the ROW_FORMAT of my table is Dynamic. Here is how I got the row format:
SELECT table_name, row_format
FROM information_schema.tables
WHERE table_schema=DATABASE() AND table_name = 'MyTable';
This functionality has been added to mysql 8.0.29. See the release notes for more details.

Alter table error code 1834

I am trying to alter a table as follows. But I am receiving an Error Code:
1834 Cannot delete rows from table which is parent in a foreign key constraint 'downloads_ibfk' of table downloads.
ALTER TABLE users
MODIFY first_name VARCHAR(20) NOT NULL UNIQUE;
You obviously have a foreign key constraint blocking the ALTER TABLE.
You can deactivate the FK check by preceding your query with
SET FOREIGN_KEY_CHECKS=0;
But remember to set it back to 1 after the query.
SET FOREIGN_KEY_CHECKS=1;
By deactivating FOREIGN_KEY_CHECKS, as suggested by #zonzon, you may get some unexpected results.
The error could also be due to the initial column schema and an incomplete ALTER TABLE query.
If you have the same issue, here is how I fixed it:
My initial column schema was:
# users.login | varchar(128) | collate utf8_bin | not null;
ALTER TABLE users ADD login varchar(128) COLLATE 'utf8_bin' NOT NULL;
What I was trying to execute, without success:
ALTER TABLE users CHANGE COLUMN login login varchar(128) NULL DEFAULT NULL;
# Cannot delete rows from table which is parent in a foreign key constraint '%s' of table '%s'
What I have executed with success:
ALTER TABLE Internaute CHANGE COLUMN login login varchar(128) COLLATE 'utf8_bin' NULL DEFAULT NULL;
# This query is more complete, I indicated the column's `COLLATE`. Otherwise the default collation is applied.
Why my first query didn't work?
In this query, I was also changing the collation (to the default one), so I think, my ALTER TABLE operation used the COPY algorithm to process my request.
Using this algorithm, a deletion is performed at some point. This is why you could get the error Cannot delete rows from table ... in an ALTER TABLE operation.
By default, the ALTER TABLE operations use other algorithms (INSTANT or INPLACE) that prevent the delete step. But, an ALTER TABLE operation that changes a column's collation is not supported by these other algorithms.
You can get more information here about the ALTER TABLE algorithms and their supported operations.

Test before changing MySQL column type

I have a table with a column of type INT(7) and I want to make this a foreign key constraint on the primary key of another table. However, the primary key is type INT(11) UNSIGNED, so I need to change INT(7) to match that in order for the foreign key to be created.
Although I don't expect to have any problems converting an INT(7) to INT(11) UNSIGNED (I have checked the column to be changed and it has no unsigned values), is there any way to ask MySQL which rows it would alter the value of? I will take a backup anyway, but I would like to be able to find out if there are likely to be any problems beforehand as I can potentially fix them before running the ALTER TABLE statement.
run
CREATE TABLE tmp SELECT yourcolumnname AS x, yourcolumnname AS y FROM yourtable;
ALTER TABLE tmp MODIFY COLUMN x INT(11) UNSIGNED;
SELECT * FROM tmp WHERE x!=y;
DROP TABLE tmp;
Yes, ALTER TABLE doesn't commit if the TEMPORARY keyword is used.
ALTER TEMPORARY TABLE .... [your code]
Source
EDIT: I just noticed this:
"However, although no implicit commit occurs, neither can the
statement be rolled back. Therefore, use of such statements will
violate transaction atomicity: For example, if you use CREATE
TEMPORARY TABLE and then roll back the transaction, the table remains
in existence."
So I'm not sure about ALTER.

How to add AUTO_INCREMENT to an existing column?

How do I add auto_increment to an existing column of a MySQL table?
I think you want to MODIFY the column as described for the ALTER TABLE command. It might be something like this:
ALTER TABLE users MODIFY id INTEGER NOT NULL AUTO_INCREMENT;
Before running above ensure that id column has a Primary index.
Method to add AUTO_INCREMENT to a table with data while avoiding “Duplicate entry” error:
Make a copy of the table with the data using INSERT SELECT:
CREATE TABLE backupTable LIKE originalTable;
INSERT backupTable SELECT * FROM originalTable;
Delete data from originalTable (to remove duplicate entries):
TRUNCATE TABLE originalTable;
To add AUTO_INCREMENT and PRIMARY KEY
ALTER TABLE originalTable ADD id INT PRIMARY KEY AUTO_INCREMENT;
Copy data back to originalTable (do not include the newly created column (id), since it will be automatically populated)
INSERT originalTable (col1, col2, col3)
SELECT col1, col2,col3
FROM backupTable;
Delete backupTable:
DROP TABLE backupTable;
More on the duplication of tables using CREATE LIKE:
Duplicating a MySQL table, indices, and data
Alter table table_name modify column_name datatype(length) AUTO_INCREMENT PRIMARY KEY
You should add primary key to auto increment, otherwise you got error in mysql.
Simply just add auto_increment Constraint In column or MODIFY COLUMN :-
ALTER TABLE `emp` MODIFY COLUMN `id` INT NOT NULL UNIQUE AUTO_INCREMENT FIRST;
Or add a column first then change column as -
1. Alter TABLE `emp` ADD COLUMN `id`;
2. ALTER TABLE `emp` CHANGE COLUMN `id` `Emp_id` INT NOT NULL UNIQUE AUTO_INCREMENT FIRST;
This worked for me in case you want to change the AUTO_INCREMENT-attribute for a not-empty-table:
1.)Exported the whole table as .sql file
2.)Deleted the table after export
2.)Did needed change in CREATE_TABLE command
3.)Executed the CREATE_TABLE and INSERT_INTO commands from the .sql-file
...et viola
I managed to do this with the following code:
ALTER TABLE `table_name`
CHANGE COLUMN `colum_name` `colum_name` INT(11) NOT NULL AUTO_INCREMENT FIRST;
This is the only way I could make a column auto increment.
INT(11) shows that the maximum int length is 11, you can skip it if you want.
Alter table table_name modify table_name.column_name data_type AUTO_INCREMENT;
eg:
Alter table avion modify avion.av int AUTO_INCREMENT;
if you have FK constraints and you don't want to remove the constraint from the table. use "index" instead of primary. then you will be able to alter it's type to auto increment
I had existing data in the first column and they were 0's.
First I made the first column nullable.
Then I set the data for the column to null.
Then I set the column as an index.
Then I made it a primary key with auto incrementing turned on. This is where I used another persons answer above:
ALTER TABLE `table_name` CHANGE COLUMN `colum_name` `colum_name` INT(11) NOT NULL AUTO_INCREMENT FIRST;
This Added numbers to all the rows of this table starting at one. If I ran the above code first it wasn't working because all the values were 0's. And making it an index was also required before making it auto incrementing.
Next I made the column a primary key.
This worked in my case , if you want to change the column attribute to auto-increment which is already having some data
1.GO to structure, select the column to want to change.
2.After selecting the column , choose primary key from the options below.
[1]: https://i.stack.imgur.com/r7w8f.png
3.Then change the column attribute to auto-increment using alter method
This is to alter the column adding PRIMARY key:
ALTER TABLE `schema_name`.`table_name`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ,
ADD UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE,
ADD PRIMARY KEY (`id`);
I copied it from MySQL Workbench... I got curious to see if it was possible to do it all in one command. I'm a little rusty in SQL.
If you are working in an specific schema, you don't need to specify it.
The above statement will create the index, set the column as the PRIMARY KEY as well with just one query.
KEEP IN MIND: There could not be duplicated values in the same column, if there are, the statement will fail to commit.
ALTER TABLE Table name ADD column datatype AUTO_INCREMENT,ADD primary key(column);

What could cause duplicate ids on a auto increment primary key field (mysql)?

RESOLVED
From the developer: the problem was that a previous version of the code was still writing to the table which used manual ids instead of the auto increment. Note to self: always check for other possible locations where the table is written to.
We are getting duplicate keys in a table. They are not inserted at the same time (6 hours apart).
Table structure:
CREATE TABLE `table_1` (
`sales_id` int(10) unsigned NOT NULL auto_increment,
`sales_revisions_id` int(10) unsigned NOT NULL default '0',
`sales_name` varchar(50) default NULL,
`recycle_id` int(10) unsigned default NULL,
PRIMARY KEY (`sales_id`),
KEY `sales_revisions_id` (`sales_revisions_id`),
KEY `sales_id` (`sales_id`),
KEY `recycle_id` (`recycle_id`)
) ENGINE= MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=26759 ;
The insert:
insert into `table_1` ( `sales_name` ) VALUES ( "Blah Blah" )
We are running MySQL 5.0.20 with PHP5 and using mysql_insert_id() to retrieve the insert id immediately after the insert query.
I have had a few duplicate key error suddenly appear in MySql databases in the past even though the primary key is defined and auto_increment. Each and every time it has been because the table has become corrupted.
If it is corrupt performing a check tables should expose the problem. You can do this by running:
CHECK TABLE tbl_name
If it comes back as corrupt in anyway (Will usually say the size is bigger than it actually should be) then just run the following to repair it:
REPAIR TABLE tbl_name
Does the sales_id field have a primary (or unique) key? If not, then something else is probably making inserts or updates that is re-using existing numbers. And by "something else" I don't just mean code; it could be a human with access to the database doing it accidentally.
As the other said; with your example it's not possible.
It's unrelated to your question, but you don't have to make a separate KEY for the primary key column -- it's just adding an extra not-unique index to the table when you already have the unique (primary) key.
We are getting duplicate keys in a table.
Do you mean you are getting errors as you try to insert, or do you mean you have some values stored in the column more than once?
Auto-increment only kicks in when you omit the column from your INSERT, or try to insert NULL or zero. Otherwise, you can specify a value in an INSERT statement, over-riding the auto-increment mechanism. For example:
INSERT INTO table_1 (sales_id) VALUES (26759);
If the value you specify already exists in the table, you'll get an error.
Please post the results of this query:
SELECT `sales_id`, COUNT(*) AS `num`
FROM `table_1`
GROUP BY `sales_id`
HAVING `num` > 1
ORDER BY `num` DESC
If you have a unique key on other fields, that could be the problem.
If you have reached the highest value for your auto_increment column MySQL will keep trying to re-insert it. For example, if sales_id was a tinyint column, you would get duplicate key errors after you reached id 127.