I already have a table, simplified example:
CREATE TABLE t (c INT NOT NULL);
And I need to change column default value to NULL, so I tried:
ALTER TABLE t ALTER COLUMN c SET DEFAULT NULL;
but I got the error "Error Code: 1067. Invalid default value for 'c'".
It looks really strange, because query conforms with official docs.
I even tried to:
ALTER TABLE t ALTER COLUMN c DROP DEFAULT;
and after it to make a 'SET DEFAULT NULL' query, but the same error occurred.
It's interesting, that query like:
ALTER TABLE t ALTER COLUMN c SET DEFAULT 1;
executed without errors.
I know, that it is possible to change column default value to NULL in my case using:
ALTER TABLE t MODIFY COLUMN c INT NULL;
but this query is really slow on big tables (it is much slower, than queries like 'SET DEFAULT 1')
So, how to just change default value to NULL?
I mean, without any overhead caused by 'MODIFY COLUMN' command.
Details: MySQL x64 version 5.7.10, Win8. Tested using MySQL Workbench.
By creating column as NOT NULL you have created a CONSTRAINT - declaring that values entered into that column may never be NULL.
A default value of NULL (set to null is value not present during INSERT) would create invalid data.
As sadly nullability constraint is part of the datatype in mysql the only way to make the column nullable will be
ALTER TABLE t MODIFY COLUMN c INT NULL;
Related
I can't figure out why my alter table query throws an error. Currently, this is a (DATETIME) column with default value NULL.
My wish is to alter it so datetime value gets automatically populated when I update a row. I'm trying to write an alter statement, but I can't figure out why mine is throwing the error.
My alter statement
ALTER TABLE `mydb`.`orders` CHANGE COLUMN `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP '{}';
And this is the error that I'm getting
16:28:34 ALTER TABLE `mydb`.`orders` CHANGE COLUMN `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP '{}' Error Code: 1064. 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 'NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP '{}'' at line 1 0.00041 sec
I'm using MySQL version 5.7
The CHANGE COLUMN alteration is used when you might want to change the name of the column, and requires you to provide the new name after the old name. If you're not renaming the column, you have to provide the name twice. Your command tries to rename the date_u column to DATETIME, and it's missing the datatype before the NULL keyword.
Use MODIFY COLUMN instead. It's the same, but doesn't allow renaming, so doesn't require you to give the column name twice.
ALTER TABLE `mydb`.`orders` MODIFY COLUMN `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP;
I'm also not sure what you intended with '{}' at the end, but I don't think it's valid syntax, either, so I've removed it.
You're missing to name the new column.
change this:
ALTER TABLE `mydb`.`orders`
CHANGE COLUMN `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP '{}';
into this:
ALTER TABLE `mydb`.`orders`
CHANGE COLUMN `date_u` `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP;
Notice the column name is typed twic, because you want the column name to stay the same, formerly here's the change column syntax:
ALTER TABLE `table_name`
CHANGE COLUMN `column_name` `column_new_name` (...);
Or, you can just you modify column syntax:
ALTER TABLE `mydb`.`orders` MODIFY COLUMN `date_u` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP;
Ps: I don't get what you mean by '{}' so I removed it because I think it's not a valid syntax.
Hope I pushed you further.
I have the following line in a .sql file from a mysql db:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50) DEFAULT NULL;
I would like to convert it into syntax that postgresql would understand. In my personal tests, I was only able to get it to work by breaking it down into two separate statements, like so:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL;
Just wondering if there's a way to consolidate the two statements back into one, but one that postgresql will be happy with?
Thanks!
The statement you posted is not valid syntax at all:
SQL Fiddle
To change the type in MySQL, you would use CHANGE or MODIFY.
To change the default you would use DROP DEFAULT or SET DEFAULT NULL.
If the intention was to change the type and reset the column default:
Like in MySQL, you can pack multiple actions into a single ALTER TABLEstatement in Postgres .
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL
,ALTER COLUMN ip_addr TYPE VARCHAR(50);
Per documentation:
The main reason for providing the option to specify multiple changes
in a single ALTER TABLE is that multiple table scans or rewrites can
thereby be combined into a single pass over the table.
But if there was a DEFAULT on the column that is incompatible with the new type, you have to run two separate statements:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL;
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
Doesn't matter in this case anyway.
As #Gordon Linoff states in the comments, postgreSQL by default sets a value to null unless a value is given or the default is changed to something else;
therefore, all you'll need is:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
The PostgreSQL ALTER TABLE syntax diagram doesn't show any way to combine changing a data type and changing a default value in a single SQL statement. You can't simply omit set default null in the general case. For example,
create table test (
column_1 char(10) not null default 'a'
);
alter table test alter column column_1 type varchar(50);
insert into test values (default);
select * from test;
column_1
--
a
Instead, either rewrite as two independent statements (which you already know how to do), or as two statements in a single transaction.
I am adding the following column to a table and I am surprised it doesn't give an error because there is no default value for the column and there is data in the table. When I executed this, the rows with data got a default value of 0 with STRICT_ALL_TABLES.
Is this expected behavior? I couldn't find it documented anywhere.
ALTER TABLE phppos_receivings ADD COLUMN location_id INT(11) NOT NULL;
I'm using PHPMyAdmin and I try to add the NOT NULL constraint to a column of my table.
PHPMyAdmin accepts my following query :
ALTER TABLE `wall` MODIFY `token_message` varchar(40) NOT NULL;
But I can still insert empty strings (=NULL), I don't understand why.
PS : If you're going to give me some other queries to add this constraint, note I've have tried these 3 which don't work in my PHPMyAdmin (kind of error : #1064 - You have an error in your SQL syntax; check the manual) :
ALTER TABLE `wall` ALTER COLUMN `token_message` SET NOT NULL;
ALTER TABLE `wall` ALTER COLUMN `token_message` varchar(40) NOT NULL;
ALTER TABLE `wall` MODIFY `token_message` CONSTRAINTS token_message_not_null NOT NULL;
You wrote, "I can still insert empty strings (=NULL)," which sounds like a misunderstanding. In SQL, an empty string does not evaluate to NULL, or vice versa. Try inserting an empty string and doing SELECT from wall where token_message is NULL. You should get zero rows back. Then try doing an insert where you specify NULL (unquoted) as the value for your column, and you should get the expected error message.
If those tests work as expected, then everything is fine, and your problem is actually that you want to prevent blank strings from being inserted. Check out this question for suggestions, or just check for blank strings during validation, before the query.
MySQL's column alter syntax requires you to completely re-specify the column. You can't just change one attribute of a column, you have to re-define it completely:
ALTER TABLE wall MODIFY token_message varchar(40) NOT NULL default ''
The only 'SET' version allowed is to change the default value.
ref: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
I think this is a matter of scrubbing your inputs. As octern mentioned, an empty string ('') is not a NULL value in sql. The best way to handle this is to only allow updates through a store procedure which strips out empty strings, even space characters:
CREATE PROC InsertIntoMyDb (#MyVarChar VARCHAR(2000)) AS
SET #MyVarChar = NULLIF(RTRIM(LTRIM(#MyVarChar)), '')
INSERT INTO [TBL] (MyVarChar)
VALUES #MyVarChar
This will truncate any number of spaces to an empty string, turn an empty string into a NULL, and then it will not allow the NULL value to be inserted based on the constraint you already have in place.
Try to use this query
Alter table table_name
change column_name column_name datatype(length) definition
ie,
Alter table wall
change tocken_message tocken_message varchar(40) NOT NULL DEFAULT
I have a table with about 10K rows, which I am trying to alter so that the field fielddelimiter is never null. I am attempting to do an alter statement, expecting any null values to be changed to the default value, but I get an error back from the sql statement.
alter table merchant_ftp_account modify column `fielddelimiter` char(1) NOT NULL DEFAULT 't';
17:08:48 [ALTER - 0 row(s), 0.000 secs] [Error Code: 1265, SQL State: 01000] Data truncated for column 'fielddelimiter' at row 3987
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec [0 successful, 0 warnings, 1 errors]
As I understand it this means that the data exceeds the field size at this row, but (a) the data in the field is (null) at that row, and (b) I am able to update that row directly with the value 't', and I don't get a truncation error. If I update that row with a nonnull value and try to re-run the alter statement, it fails at the next row where fielddelimiter is null. [ETA: I get that MySQL could update in any direction, but I can actually track its progress as I change rows.]
There's a warning in the MySQL docs:
Warning This conversion may result in alteration of data. For example, if you shorten a
string column, values may be truncated. To prevent the operation from succeeding if
conversions to the new data type would result in loss of data, enable strict SQL mode
before using ALTER TABLE (see Section 5.1.6, “Server SQL Modes”).
But the values that it's supposedly truncating are nulls. Can anybody explain to me what is going on here? And how to resolve it?
[ETA: The existing fielddelimiter field definition is char(1) (allows nulls, no default value), so it should not have values > 1 char, and a select confirms that it does not. The distinct values in the field are NULL, '' (empty string), 'p', 't', and 'y'.]
I have just encountered this error, and it seems the solution was to use the IGNORE statement:
ALTER IGNORE TABLE `table` CHANGE COLUMN `col` `col` int(11) NOT NULL;
Note that you may still have data truncation issues, so be sure this is the desired result. Using the IGNORE statement it will suppress the data truncated errors for NULL values in columns (and possibly other errors!!!)
If your column has NULL values, you can't alter it to be "NON NULL". Change the NULL values first to something else, then try it.
First remove any null values
UPDATE merchant_ftp_account SET fielddelimiter='t' WHERE fielddelimiter IS NULL;
Then
ALTER TABLE merchant_ftp_account MODIFY COLUMN `fielddelimiter` char(1) NOT NULL DEFAULT 't';
In my case I was setting the column to NOT NULL
ALTER TABLE `request_info`
CHANGE COLUMN `col_2` `col_2`
VARCHAR(2000)
NOT NULL -- here was setting it to NULL when the existing col allowed NULL
AFTER `col_1`
when previously I set the column to DEFAULT NULL (i.e. allow NULL values), so if you want to allow NULL then you can do the following:
ALTER TABLE `request_info`
CHANGE COLUMN `col_2` `col_2`
VARCHAR(2000)
DEFAULT NULL -- changed from NOT --> DEFAULT
AFTER `col_1`