Add the NOT NULL constraint to a column - mysql

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

Related

change column definition in existing table

I need to edit a datatype (IS_NULLABLE) from my column tag.
Nothing works, i have tried like that:
ALTER TABLE veille
ALTER COLUMN tag
SET IS_NULLABLE false
or like that :
ALTER TABLE veille ALTER COLUMN tag Modify datatype false
but doesn't work too, i have this error :
Error: 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 'IS_NULLABLE false' at line 3.
Edit : Resolved, the problem was my column has null values, i have changed these null values and all works fine.
use
ALTER TABLE veille ALTER COLUMN tag datatype
columns are nullable by default, As long as the column is not declared UNIQUE or NOT NULL, there shouldn't be any problems.
refer to this question: How do I modify a MySQL column to allow NULL?
No need for datatype false
Just use the query like below
alter table table_name modify column tag <datatype> not null;
try ALTER TABLE veille_ndd_hist MODIFY tag bit(1) NOT NULL DEFAULT b'0;
you may also try ALTER TABLE veille_ndd_hist CHANGE COLUMN tag tag BIT NOT NULL
Note that when using MODIFY, you need to specify the full column definition, including DEFAULT value if was defined.
side note: of course make sure that the column does not have any null values

Convert default column value from datetime to varchar

I have to add a varchar column to a table which defaults to the current timestamp. To do this I somehow need to convert the value from datetime to varchar.
I tried the following
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(NOW(), CHAR);
or
ALTER TABLE `TableName`
CHANGE COLUMN `DocumentID` `DocumentID` VARCHAR(150) NULL DEFAULT CONVERT(CURRENT_TIMESTAMP, CHAR);
I always get an error message, that my syntax is wrong. I am using MariaDB and HeidiSQL. Is there a way to do this?
EDIT: I am basically looking for a MySQL equivalent of the following SQL Server statement:
ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [DF_TableName_DocumentID] DEFAULT (getdate()) FOR [DocumentID]
MariaDB document says
In MariaDB 10.2.1 you can use most functions in DEFAULT. Expressions
should have parentheses around them.
Hence you may check for the version of MariaDB and use the right syntax (parenthesis around expression):
(CONVERT(CURRENT_TIMESTAMP, CHAR))
Update
As an alternative, you may use Trigger to set the function value for the stable releases (< 10.2)
If you use CURRENT_TIMESTAMP as default value, you must use the datatype that the function retrieves, in this case is a timestamp as you can see in the docs.
I don't know the reasons that may lead you to save this as a varchar. I'm not sure but I think that MariaDB doesn't allow to call functions as default values so you can't convert CURRENT_TIMESTAMP as varchar. You have an alternative approach, make an after insert trigger updating the field (you can call CONVERT(CURRENT_TIMESTAMP, VARCHAR) inside a trigger).
Either way, I recomend to stay with timestamp.
I see the field is called "DocumentID", perhaps you want to save a hash value as identifier? You can archieve this with virtual columns. An example.

Failed to set default null value for column

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;

mySQL adding column with NULL values

I am using mySQL and am trying to get my head around the difference between NULL and empty. If I add a column to my table using...
alter table data add result VARCHAR(4);
Then every field in the column is automatically populated with NULL.
Does this take up any more space than an empty field? How could I add that column with blank values instead?
You can use default, if you don;t like nulls, but Null is more descriptive:
alter table data add result VARCHAR(4) DEFAULT ''
Generally you should be using null, as it means -none has set a value to this column.
As for the space I am not aware is MySQL is treating empty values, but I assume that NULL takes less space, because NULL is generally a singleton in most languages.

converting mysql scripts to postgresql script

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.