Add new column to a table without constraint in SQL - sql

I want to add a column with the same value across the rows to a table. I use this:
ALTER TABLE dbo.MyTable
ADD MyColumnName VARCHAR(20) NULL
DEFAULT 'A201412'
WITH VALUES
It almost works fine but it creates some stupid constraint to a column. Other existing columns do not have any constraints. How to create a column without a constraint?

That "stupid" constraint is what the DEFAULT keyword is really used for.
Using DEFAULT when you create a column means that that value will be used when no value is specified in an INSERT for the column, for example
CREATE TABLE test (
a Int
, b Varchar(5) DEFAULT 'foo'
);
INSERT INTO test(a) VALUES (1)
will generate the row
a | b
1 | foo
instead of the row
a | b
1 | NULL
As Gordon already said, don't add the DEFAULT, then use an UPDATE to put the initial value in the new column
ALTER TABLE dbo.MyTable ADD MyColumnName VARCHAR(20);
UPDATE dbo.MyTable SET MyColumnName = 'A201412'

Just don't add the default clause. Simply use:
ALTER TABLE dbo.MyTable ADD MyColumnName VARCHAR(20);

Related

Adding a NOT NULL column to a Redshift table

I'd like to add a NOT NULL column to a Redshift table that has records, an IDENTITY field, and that other tables have foreign keys to.
In PostgreSQL, you can add the column as NULL, fill it in, then ALTER it to be NOT NULL.
In Redshift, the best I've found so far is:
ALTER TABLE my_table ADD COLUMN new_column INTEGER;
-- Fill that column
CREATE TABLE my_table2 (
id INTEGER IDENTITY NOT NULL SORTKEY,
(... all the fields ... )
new_column INTEGER NOT NULL,
PRIMARY KEY(id)
) DISTSTYLE all;
UNLOAD ('select * from my_table')
to 's3://blah' credentials '<aws-auth-args>' ;
COPY my_table2
from 's3://blah' credentials '<aws-auth-args>'
EXPLICIT_IDS;
DROP table my_table;
ALTER TABLE my_table2 RENAME TO my_table;
-- For each table that had a foreign key to my_table:
ALTER TABLE another_table ADD FOREIGN KEY(my_table_id) REFERENCES my_table(id)
Is this the best way of achieving this?
You can achieve this w/o having to load to S3.
modify the existing table to create the desired column w/ a default value
update that column in some way (in my case it was copying from another column)
create a new table with the column w/o a default value
insert into the new table (you must list out the columns rather than using (*) since the order may be the same (say if you want the new column in position 2)
drop the old table
rename the table
alter table to give correct owner (if appropriate)
ex:
-- first add the column w/ a default value
alter table my_table_xyz
add visit_id bigint NOT NULL default 0; -- not null but default value
-- now populate the new column with whatever is appropriate (the key in my case)
update my_table_xyz
set visit_id = key;
-- now create the new table with the proper constraints
create table my_table_xzy_new
(
key bigint not null,
visit_id bigint NOT NULL, -- here it is not null and no default value
adt_id bigint not null
);
-- select all from old into new
insert into my_table_xyz_new
select key, visit_id, adt_id
from my_table_xyz;
-- remove the orig table
DROP table my_table_xzy_events;
-- rename the newly created table to the desired table
alter table my_table_xyz_new rename to my_table_xyz;
-- adjust any views, foreign keys or permissions as required

how to add not null column in existing table and then insert values in that column?

how to add not null column in existing table and then insert values in that column ??
in sql...
If you want to add a NOT NULL column you must specify a DEFAULT:
ALTER TABLE YourTable
ADD SomeColumn INT NOT NULL
CONSTRAINT DF_YourTable_SomeColumn DEFAULT(0);
Other possibility is to add it with NULL, add your data and alter it to NOT NULL later (see ALTER TABLE)
EDIT: Your comment about "how to insert values"...
This depends very much in your needs. If you want to set all rows to the same value it is:
UPDATE YourTable SET SomeColumn=0;

Add a column to a table with a default value equal to the value of an existing column

How to add a column to a SQL Server table with a default value that is equal to value of an existing column?
I tried this T-SQL statement:
ALTER TABLE tablename
ADD newcolumn type NOT NULL DEFAULT (oldcolumn)
but it's giving an error:
The name "oldcolumn" is not permitted in this context. Valid
expressions are constants, constant expressions, and (in some
contexts) variables. Column names are not permitted.
Try this:
ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go
The AFTER INSERT trigger approach involves overhead due to the extra UPDATE statement. I suggest using an INSTEAD OF INSERT trigger, as follows:
CREATE TRIGGER tablename_on_insert ON tablename
INSTEAD OF INSERT
AS
INSERT INTO tablename (oldcolumn, newcolumn)
SELECT oldcolumn, ISNULL(newcolumn, oldcolumn)
FROM inserted
This does not work though if the oldcolumn is an auto-identity column.
I don't like them very much but here is how you could do this with an AFTER INSERT trigger:
CREATE TRIGGER TableX_AfterInsert_TRG
ON TableX
AFTER INSERT
AS
UPDATE TableX AS t
SET t.newcolumn = t.oldcolumn
FROM Inserted AS i
WHERE t.PK = i.PK ; -- where PK is the PRIMARY KEY of the table
You can use computed column to insert new column in a table based on an existing column value
ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn) PERSISTED;
OR, if you want to make some changes to the value based on existing column value, use
ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn * 1.5) PERSISTED;
To extend Kapil's answer, and avoid the unwanted default constraint, try this:
ALTER TABLE tablename ADD newcolumn type NOT NULL CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN DEFAULT -9999
Go
Update tablename SET newcolumn = oldcolumn
Go
ALTER TABLE tablename DROP CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN
Go
Replace -9999 by 'noData' if your type is varchar, nvarchar, datetime,... or by any compatible data for other types: specific value doesn't matter, it will be wiped by the 2nd instruction.
For my case, I want to add a new not null unique column named CODE but I don't know about the value at the creation time. I set the default value for it by get a default value from NewID() then update later.
ALTER TABLE [WIDGET] ADD [CODE] CHAR(5) NOT NULL DEFAULT(SUBSTRING(CONVERT(CHAR(36), NEWID()), 1, 5))
ALTER TABLE [dbo].[WIDGET] WITH CHECK ADD CONSTRAINT [UQ_WIDGET_CODE] UNIQUE ([CODE])
Use a computed column, which will even work with IDENTITY column values:
CREATE TABLE #This
( Id INT IDENTITY(1,1)
,MyName VARCHAR(10)
,FullName AS (Myname + CONVERT(VARCHAR(10),Id)) PERSISTED);
INSERT #This VALUES ('Item'),('Item');
SELECT * FROM #This;
DROP TABLE #This;
yields the following:
I think it will work if you use Set Identity_Insert <TableName> OFF and after the insert Statement that you wrote just use Set Identity_Insert <TableName> ON.

Can I add a not null column without DEFAULT value

Can I add a column which is I specify as NOT NULL,I don't want to specify the DEFAULT value but MS-SQL 2005 says:
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 'test' cannot be added to non-empty table 'shiplist' because it does not satisfy these conditions.
If YES, please let me know the syntax, if No please specify the reason.
No, you can't.
Because if you could, SQL wouldn't know what to put as value in the already existing records. If you didn't have any records in the table it would work without issues.
The simplest way to do this is create the column with a default and then remove the default.
ALTER TABLE dbo.MyTable ADD
MyColumn text NOT NULL CONSTRAINT DF_MyTable_MyColumn DEFAULT 'defaultValue'
ALTER TABLE dbo.MyTable
DROP CONSTRAINT DF_MyTable_MyColumn
Another alternative would be to add the column without the constraint, fill the values for all cells and add the constraint.
Add the column to the table, update the existing rows so none of them are null, and then add a "not null" constraint.
No - SQL Server quite reasonably rejects this, because it wouldn't know what value existing rows should have
It's easy to create a DEFAULT at the same time, and then immediately drop it.
I use this approach to insert NOT NULL column without default value
ALTER TABLE [Table] ADD [Column] INT NULL
GO
UPDATE [Table] SET [Column] = <default_value>
ALTER TABLE [Table] ALTER COLUMN [Column] INT NOT NULL
No.
Just use empty string '' (in case of character type) or 0 (if numeric), etc as DEFAULT value
No you cannot. But you can consider to specify the default value to ('')
No, you can't, as SQL Server, or any other database engines will force this new column to be null for existing rows into your data table. But since you do not allow a NULL, you are required to provide a default value in order to respect your own constraint. This falls under great sense! The DBE will not extrapolate a value for non-null values for the existing rows.
#Damien_The_Unbeliever's comment ,
Is it adding computed column? Neither question nor answer implied anything like that. In case of computed column the error states:
"Only UNIQUE or PRIMARY KEY constraints can be created on computed columns, while CHECK, FOREIGN KEY, and NOT NULL constraints require that computed columns be persisted"
OK, if to continue this guessing game, here is my script illustrating the adding of "NOT NULL" column in one "ALTER TABLE" step:
CREATE TABLE TestInsertComputedColumn
(
FirstName VARCHAR(100),
LastName CHAR(50)
);
insert into TestInsertComputedColumn(FirstName,LastName)
select 'v', 'gv8';
select * from TestInsertComputedColumn;
ALTER TABLE TestInsertComputedColumn
ADD FullName As FirstName + LastName PERSISTED NOT NULL;
select * from TestInsertComputedColumn;
--drop TABLE TestInsertComputedColumn;
I used below approach it worked for me
Syntax:
ALTER TABLE <YourTable> ADD <NewColumn> <NewColumnType> NOT NULL DEFAULT <DefaultValue>
Example:
ALTER TABLE Tablename ADD ColumnName datetime NOT NULL DEFAULT GETDATE();
As an option you can initially create Null-able column, then update your table column with valid not null values and finally ALTER column to set NOT NULL constraint:
ALTER TABLE MY_TABLE ADD STAGE INT NULL
GO
UPDATE MY_TABLE SET <a valid not null values for your column>
GO
ALTER TABLE MY_TABLE ALTER COLUMN STAGE INT NOT NULL
GO

Add a column with a default value to an existing table in SQL Server

How can I add a column with a default value to an existing table in SQL Server 2000 / SQL Server 2005?
Syntax:
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
WITH VALUES
Example:
ALTER TABLE SomeTable
ADD SomeCol Bit NULL --Or NOT NULL.
CONSTRAINT D_SomeTable_SomeCol --When Omitted a Default-Constraint Name is autogenerated.
DEFAULT (0)--Optional Default-Constraint.
WITH VALUES --Add if Column is Nullable and you want the Default Value for Existing Records.
Notes:
Optional Constraint Name:
If you leave out CONSTRAINT D_SomeTable_SomeCol then SQL Server will autogenerate
a Default-Contraint with a funny Name like: DF__SomeTa__SomeC__4FB7FEF6
Optional With-Values Statement:
The WITH VALUES is only needed when your Column is Nullable
and you want the Default Value used for Existing Records.
If your Column is NOT NULL, then it will automatically use the Default Value
for all Existing Records, whether you specify WITH VALUES or not.
How Inserts work with a Default-Constraint:
If you insert a Record into SomeTable and do not Specify SomeCol's value, then it will Default to 0.
If you insert a Record and Specify SomeCol's value as NULL (and your column allows nulls),
then the Default-Constraint will not be used and NULL will be inserted as the Value.
Notes were based on everyone's great feedback below.
Special Thanks to:
#Yatrix, #WalterStabosz, #YahooSerious, and #StackMan for their Comments.
ALTER TABLE Protocols
ADD ProtocolTypeID int NOT NULL DEFAULT(1)
GO
The inclusion of the DEFAULT fills the column in existing rows with the default value, so the NOT NULL constraint is not violated.
When adding a nullable column, WITH VALUES will ensure that the specific DEFAULT value is applied to existing rows:
ALTER TABLE table
ADD column BIT -- Demonstration with NULL-able column added
CONSTRAINT Constraint_name DEFAULT 0 WITH VALUES
ALTER TABLE <table name>
ADD <new column name> <data type> NOT NULL
GO
ALTER TABLE <table name>
ADD CONSTRAINT <constraint name> DEFAULT <default value> FOR <new column name>
GO
ALTER TABLE MYTABLE ADD MYNEWCOLUMN VARCHAR(200) DEFAULT 'SNUGGLES'
The most basic version with two lines only
ALTER TABLE MyTable
ADD MyNewColumn INT NOT NULL DEFAULT 0
Beware when the column you are adding has a NOT NULL constraint, yet does not have a DEFAULT constraint (value). The ALTER TABLE statement will fail in that case if the table has any rows in it. The solution is to either remove the NOT NULL constraint from the new column, or provide a DEFAULT constraint for it.
Use:
-- Add a column with a default DateTime
-- to capture when each record is added.
ALTER TABLE myTableName
ADD RecordAddedDate SMALLDATETIME NULL DEFAULT (GETDATE())
GO
If you want to add multiple columns you can do it this way for example:
ALTER TABLE YourTable
ADD Column1 INT NOT NULL DEFAULT 0,
Column2 INT NOT NULL DEFAULT 1,
Column3 VARCHAR(50) DEFAULT 'Hello'
GO
To add a column to an existing database table with a default value, we can use:
ALTER TABLE [dbo.table_name]
ADD [Column_Name] BIT NOT NULL
Default ( 0 )
Here is another way to add a column to an existing database table with a default value.
A much more thorough SQL script to add a column with a default value is below including checking if the column exists before adding it also checkin the constraint and dropping it if there is one. This script also names the constraint so we can have a nice naming convention (I like DF_) and if not SQL will give us a constraint with a name which has a randomly generated number; so it's nice to be able to name the constraint too.
-------------------------------------------------------------------------
-- Drop COLUMN
-- Name of Column: Column_EmployeeName
-- Name of Table: table_Emplyee
--------------------------------------------------------------------------
IF EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'table_Emplyee'
AND COLUMN_NAME = 'Column_EmployeeName'
)
BEGIN
IF EXISTS ( SELECT 1
FROM sys.default_constraints
WHERE object_id = OBJECT_ID('[dbo].[DF_table_Emplyee_Column_EmployeeName]')
AND parent_object_id = OBJECT_ID('[dbo].[table_Emplyee]')
)
BEGIN
------ DROP Contraint
ALTER TABLE [dbo].[table_Emplyee] DROP CONSTRAINT [DF_table_Emplyee_Column_EmployeeName]
PRINT '[DF_table_Emplyee_Column_EmployeeName] was dropped'
END
-- ----- DROP Column -----------------------------------------------------------------
ALTER TABLE [dbo].table_Emplyee
DROP COLUMN Column_EmployeeName
PRINT 'Column Column_EmployeeName in images table was dropped'
END
--------------------------------------------------------------------------
-- ADD COLUMN Column_EmployeeName IN table_Emplyee table
--------------------------------------------------------------------------
IF NOT EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'table_Emplyee'
AND COLUMN_NAME = 'Column_EmployeeName'
)
BEGIN
----- ADD Column & Contraint
ALTER TABLE dbo.table_Emplyee
ADD Column_EmployeeName BIT NOT NULL
CONSTRAINT [DF_table_Emplyee_Column_EmployeeName] DEFAULT (0)
PRINT 'Column [DF_table_Emplyee_Column_EmployeeName] in table_Emplyee table was Added'
PRINT 'Contraint [DF_table_Emplyee_Column_EmployeeName] was Added'
END
GO
These are two ways to add a column to an existing database table with a default value.
Use:
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
Reference: ALTER TABLE (Transact-SQL) (MSDN)
You can do the thing with T-SQL in the following way.
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
As well as you can use SQL Server Management Studio also by right clicking table in the Design menu, setting the default value to table.
And furthermore, if you want to add the same column (if it does not exists) to all tables in database, then use:
USE AdventureWorks;
EXEC sp_msforeachtable
'PRINT ''ALTER TABLE ? ADD Date_Created DATETIME DEFAULT GETDATE();''' ;
In SQL Server 2008-R2, I go to the design mode - in a test database - and add my two columns using the designer and made the settings with the GUI, and then the infamous Right-Click gives the option "Generate Change Script"!
Bang up pops a little window with, you guessed it, the properly formatted guaranteed-to-work change script. Hit the easy button.
Alternatively, you can add a default without having to explicitly name the constraint:
ALTER TABLE [schema].[tablename] ADD DEFAULT ((0)) FOR [columnname]
If you have an issue with existing default constraints when creating this constraint then they can be removed by:
alter table [schema].[tablename] drop constraint [constraintname]
This can be done in the SSMS GUI as well. I show a default date below but the default value can be whatever, of course.
Put your table in design view (Right click on the table in object
explorer->Design)
Add a column to the table (or click on the column you want to update if
it already exists)
In Column Properties below, enter (getdate()) or 'abc' or 0 or whatever value you want in Default Value or Binding field as pictured below:
ALTER TABLE ADD ColumnName {Column_Type} Constraint
The MSDN article ALTER TABLE (Transact-SQL) has all of the alter table syntax.
Example:
ALTER TABLE [Employees] ADD Seniority int not null default 0 GO
Example:
ALTER TABLE tes
ADD ssd NUMBER DEFAULT '0';
First create a table with name student:
CREATE TABLE STUDENT (STUDENT_ID INT NOT NULL)
Add one column to it:
ALTER TABLE STUDENT
ADD STUDENT_NAME INT NOT NULL DEFAULT(0)
SELECT *
FROM STUDENT
The table is created and a column is added to an existing table with a default value.
This is for SQL Server:
ALTER TABLE TableName
ADD ColumnName (type) -- NULL OR NOT NULL
DEFAULT (default value)
WITH VALUES
Example:
ALTER TABLE Activities
ADD status int NOT NULL DEFAULT (0)
WITH VALUES
If you want to add constraints then:
ALTER TABLE Table_1
ADD row3 int NOT NULL
CONSTRAINT CONSTRAINT_NAME DEFAULT (0)
WITH VALUES
This has a lot of answers, but I feel the need to add this extended method. This seems a lot longer, but it is extremely useful if you're adding a NOT NULL field to a table with millions of rows in an active database.
ALTER TABLE {schemaName}.{tableName}
ADD {columnName} {datatype} NULL
CONSTRAINT {constraintName} DEFAULT {DefaultValue}
UPDATE {schemaName}.{tableName}
SET {columnName} = {DefaultValue}
WHERE {columName} IS NULL
ALTER TABLE {schemaName}.{tableName}
ALTER COLUMN {columnName} {datatype} NOT NULL
What this will do is add the column as a nullable field and with the default value, update all fields to the default value (or you can assign more meaningful values), and finally it will change the column to be NOT NULL.
The reason for this is if you update a large scale table and add a new not null field it has to write to every single row and hereby will lock out the entire table as it adds the column and then writes all the values.
This method will add the nullable column which operates a lot faster by itself, then fills the data before setting the not null status.
I've found that doing the entire thing in one statement will lock out one of our more active tables for 4-8 minutes and quite often I have killed the process. This method each part usually takes only a few seconds and causes minimal locking.
Additionally, if you have a table in the area of billions of rows it may be worth batching the update like so:
WHILE 1=1
BEGIN
UPDATE TOP (1000000) {schemaName}.{tableName}
SET {columnName} = {DefaultValue}
WHERE {columName} IS NULL
IF ##ROWCOUNT < 1000000
BREAK;
END
Try this
ALTER TABLE Product
ADD ProductID INT NOT NULL DEFAULT(1)
GO
SQL Server + Alter Table + Add Column + Default Value uniqueidentifier
ALTER TABLE Product
ADD ReferenceID uniqueidentifier not null
default (cast(cast(0 as binary) as uniqueidentifier))
--Adding Value with Default Value
ALTER TABLE TestTable
ADD ThirdCol INT NOT NULL DEFAULT(0)
GO
IF NOT EXISTS (
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME ='TABLENAME' AND COLUMN_NAME = 'COLUMNNAME'
)
BEGIN
ALTER TABLE TABLENAME ADD COLUMNNAME Nvarchar(MAX) Not Null default
END
Add a new column to a table:
ALTER TABLE [table]
ADD Column1 Datatype
For example,
ALTER TABLE [test]
ADD ID Int
If the user wants to make it auto incremented then:
ALTER TABLE [test]
ADD ID Int IDENTITY(1,1) NOT NULL
Try with the below query:
ALTER TABLE MyTable
ADD MyNewColumn DataType DEFAULT DefaultValue
This will add a new column into the Table.
This can be done by the below code.
CREATE TABLE TestTable
(FirstCol INT NOT NULL)
GO
------------------------------
-- Option 1
------------------------------
-- Adding New Column
ALTER TABLE TestTable
ADD SecondCol INT
GO
-- Updating it with Default
UPDATE TestTable
SET SecondCol = 0
GO
-- Alter
ALTER TABLE TestTable
ALTER COLUMN SecondCol INT NOT NULL
GO
There are 2 different ways to address this problem.
Both adds a default value but adds a totally different meaning to the problem statement here.
Lets start with creating some sample data.
Create Sample Data
CREATE TABLE ExistingTable (ID INT)
GO
INSERT INTO ExistingTable (ID)
VALUES (1), (2), (3)
GO
SELECT *
FROM ExistingTable
1.Add Columns with Default Value for Future Inserts
ALTER TABLE ExistingTable
ADD ColWithDefault VARCHAR(10) DEFAULT 'Hi'
GO
So now as we have added a default column when we are inserting a new record it will default it's value to 'Hi' if value not provided
INSERT INTO ExistingTable(ID)
VALUES (4)
GO
Select * from ExistingTable
GO
Well this addresses our problem to have default value but here is a catch to the problem.
What if we want to have default value in all the columns not just the future inserts???
For this we have Method 2.
2.Add Column with Default Value for ALL Inserts
ALTER TABLE ExistingTable
ADD DefaultColWithVal VARCHAR(10) DEFAULT 'DefaultAll'
WITH VALUES
GO
Select * from ExistingTable
GO
The following script will add a new column with a default value in every possible scenario.
Hope it adds value to the question asked.
Thanks.
Well, I now have some modification to my previous answer. I have noticed that none of the answers mentioned IF NOT EXISTS. So I am going to provide a new solution of it as I have faced some problems altering the table.
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.columns WHERE table_name = 'TaskSheet' AND column_name = 'IsBilledToClient')
BEGIN
ALTER TABLE dbo.TaskSheet ADD
IsBilledToClient bit NOT NULL DEFAULT ((1))
END
GO
Here TaskSheet is the particular table name and IsBilledToClient is the new column which you are going to insert and 1 the default value. That means in the new column what will be the value of the existing rows, therefore one will be set automatically there. However, you can change as you wish with the respect of the column type like I have used BIT, so I put in default value 1.
I suggest the above system, because I have faced a problem. So what is the problem? The problem is, if the IsBilledToClient column does exists in the table table then if you execute only the portion of the code given below you will see an error in the SQL server Query builder. But if it does not exist then for the first time there will be no error when executing.
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
[WITH VALUES]