How to add a not null constraint on column containing null values - sql

I have a table with a column that contains a few null values. I want to add a NOT NULL constraint on that column without updating the existing nulls to a non-null value. I want to keep the existing null values and check for future rows that they contain a not null value for this column. Is this possible? How?

You can add an unvalidated constraint - it will not look at existing rows, but it will be checked for any new or updated rows.
ALTER TABLE mytable MODIFY mycolumn NOT NULL NOVALIDATE;
Just be aware that you won't be able to update an existing row unless it satisfies the constraint.
Also, be aware of the downside that the optimizer will not be able to take advantage of this constraint in making its plans - it has to assume that some rows may still have a null.

ALTER TABLE table_name
SET column_name = '0'
WHERE column_name IS NULL;
ALTER TABLE table_name
MODIFY COLUMN(column_name NUMBER CONSTRAINT constraint_identifier NOT NULL);
This is of course assuming that your column is a number but it's the same thing really, you would just change the '0' to a default value that isn't null.

Hammad:
I face the problem and solve like following:
Alter table thr_empl_info modify THR_EM_DESIGNATION_ID not null

Related

Modify SQL column field to be nullable, if I added constraint do I need to remove constraint as well?

I altered a table with the following script
ALTER TABLE TABLENAME ADD [flagField] CHAR(1) DEFAULT 'N' NOT NULL;
ALTER TABLE TABLENAME ADD CONSTRAINT XCK6_tablename CHECK([flagField] in ('Y', 'N'));
If I want to reverse this script to change that field in the table to allow a nullable state, do I need to remove the constraint before making the field nullable?
so if I run
ALTER TABLE TABLENAME ALTER COLUMN fieldFlag CHAR(1) NULL
will that be fine as is or should I also remove the constraint?
You only have to make the field NULLable.
The logic for constraints differs from the logic for WHERE and CASE WHEN conditions. For WHERE and CASE WHEN, NULL results are treated the same as false.
CHECK is instead validating the data. It accepts as valid anything that is not explicitly false. So, there is no need to include NULL checking in the constraint.
If you did, the correct logic would be:
CHECK (flagField in ('Y', 'N') or flagField is null)
Here is a db<>fiddle illustrating that the behavior is as described above.

SQL how to update a column with a value that depends on the value of a different column in the same table

I have a table with 2 date columns, open_date and close_date. And when I insert a new row the close_date can be null. But in the future I will want to update the close_date, and I want to ensure that the close_date is bigger than the open_date?
Thanx
I'm using oracle...
You can add a check constraint to make sure Close_date is bigger than the Open_Date,
ALTER TABLE Table_Name
ADD CONSTRAINT ck_Con_Name CHECK (Close_date > Open_Date)
To make sure a value is provided for Close_Date column and its not left null, make the column NON-NULABLE.
For this you will need to make sure first there isnt any NULL Values in that column. UPDATE the column to some defualt value. Then Alter table definition something like this...
ALTER TABLE Table_Name
ALTER COLUMN Close_date DATETIME NOT NULL;
A check constraint like this will do ask you ask:
ALTER TABLE YourTable ADD CONSTRAINT CK_open_date_before_close_date
CHECK (open_date < close_date);
This will reject any transactions that update the table to a state that violates the condition. If, for example, you updated 5 rows but only one of them violated the constraint, the entire update will fail.
Additionally, I would recommend that instead of NULL for an open-ended close date, you use a sentinel value of 99991231. There are many reasons for this, not the least of which is performance of queries (so you can do simple inequality statements without needing an OR IS NULL clause). You can additionally then make the column NOT NULL and simplify the above check condition. This also affects front-end application code positively.
UPDATE
The check constraint does not require OR close_date IS NULL in it, since if close_date is NULL, the whole expression will be evaluated to NULL, and this will not violate the CHECK constraint.
You may be needing the CHECK Constraints.
PLease refer to the link

Database column with default constraint

I am creating a database column like this:
Alter table tablename
add column columnname null
add constraint df_columnname default 0
After executing above SQL, the new column is added to table with null values.
Does the constraint df_cloumnname have no meaning here?
Please clarify on this..
If your column is nullable, then adding it with a default constraint has no impact - it can be null, and will remain null. The DEFAULT CONSTRAINT in that case only applies to new rows that are being added (and that do not explicitly specify a value for your column).
If your column were NOT NULL, then the default constraint would be applied right away.
If you're using SQL Server (you didn't specify clearly enough - SQL is the query language - but not a database product...), and you want a nullable column witha default constraint and you want the value to be applied to the existing rows, use this syntax:
ALTER TABLE dbo.tablename
ADD columnname NULL
CONSTRAINT df_columnname DEFAULT 0 WITH VALUES
Add the WITH VALUES to your command and you should get the desired result.

SQL: Create new column with default, unique value

I have added a new column, called Ordinal, to a table called Activity. The problem is that I gave it a UNIQUE constraint, set it to allow NULL (though this I won't want in the end.. I just needed to set it to that to get a little farther with the script), and did not give it a default value. I'm now running a RedGate SQL Compare script that was generated by comparing this table to a version of the Activity table that does not have the column. But I'm getting the following error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'iwt.Activity' and the index name 'IX_Activity'. The duplicate key value is (1).
So based on my research, it's trying to create a unique key constraint on the Ordinal column, but NULL is not unique. So my next step was to give it a unique value of 1 just to let the script pass. But 1 isn't going to be unique either. So, finally, my question:
Preferably in SQL Server Management Studio, how do I set a column as having a unique default value? Isn't that what I would need to create this constraint?
Thanks.
try this:
NULL will be the first constraint when you create the column.
UNIQUE will be as add constraint, you should add the second constraint.
they can run on this order with no problem (tested):
--first constraint
alter table Table_Name
add Column_Name int null
--second constraint
alter table Table_Name
add constraint Constraint_Name unique (Column_Name)
In my example :
PaymentGatewayHash is column
Cart is a table
--first query
alter table Cart
add PaymentGatewayHash NVARCHAR(20) null
--second query
CREATE UNIQUE INDEX PaymentGatewayHashUnique
ON Cart (PaymentGatewayHash)
WHERE PaymentGatewayHash IS NOT NULL
I just tested that :D

Best way to add a new column with an initial (but not default) value?

I need to add a new column to a MS SQL 2005 database with an initial value. However, I do NOT want to automatically create a default constraint on this column. At the point in time that I add the column the default/initial value is correct, but this can change over time. So, future access to the table MUST specify a value instead of accepting a default.
The best I could come up with is:
ALTER TABLE tbl ADD col INTEGER NULL
UPDATE tbl SET col = 1
ALTER TABLE tbl ALTER COLUMN col INTEGER NOT NULL
This seems a bit inefficient for largish tables (100,000 to 1,000,000 records).
I have experimented with adding the column with a default and then deleting the default constraint. However, I don't know what the name of the default constraint is and would rather not access sysobjects and put in database specific knowledge.
Please, there must be a better way.
To add the column with a default and then delete the default, you can name the default:
ALTER TABLE tbl ADD col INTEGER NOT NULL CONSTRAINT tbl_temp_default DEFAULT 1
ALTER TABLE tbl drop constraint tbl_temp_default
This filled in the value 1, but leaves the table without a default. Using SQL Server 2008, I ran this and your code, of alter update alter and did not see any noticeable difference on a table of 100,000 small rows. SSMS would not show me the query plans for the alter table statements, so I was not able to compare the resources used between the two methods.
I'd ALTER TABLE tbl ADD col INTEGER CONSTRAINT tempname DEFAULT 1 first,, and drop the explicitly named constraint after (presumably within a transaction).
Another, maybe more native, way would be:
ALTER TABLE tbl ADD COLUMN col INTEGER NOT NULL DEFAULT 1;
ALTER TABLE tbl ALTER COLUMN col DROP DEFAULT;
I'm not sure how long this function exists, but the PostgreSQL documentation goes back to version 7.1 and for 7.1 it is already described.
You can do it in an insert trigger
If you add a default constraint when creating the table, you won't know what it is called. However, if you add a constraint with ALTER TABLE, you must name the constraint. In this case, you would be able to ALTER TABLE DROP CONSTRAINT (This applies to T-SQL, not sure about other databases.)
However, this would require you to CREATE TABLE with NULL column, ALTER TABLE to add the constraint, make the column NOT NULL, and finally DROP CONSTRAINT.
I don't believe an insert trigger would work as someone else mentioned, because your rows are already added.
I think the way you describe may, in fact, be the most efficient and elegant solution.