I have a persisted computed column in a large table in in SQL Server 2005.
I want to convert it to a regular column, keeping current values.
Do I have to recreate the column and update the entire table in transaction,
or is it possible to just alter a computed column specification, and how to do it?
-- Create a new Column (unpersisted):
ALTER TABLE MyTable
ADD newColumn DatatypeOfPersistedColumn
GO
UPDATE myTable
SET newColumn = PersistedColumn
GO
-- Delete the persisted column
ALTER TABLE MyTable
DROP COLUMN PersistedColumn
GO
-- Rename new column to old name
EXEC sp_rename 'MyTable.newColumn', 'PersistedColumn', 'COLUMN'
GO
The poster wants to keep the name of the column. I have added a line at the end of Mitch's code to do a rename after dropping the PersistedColumn
-- Create a new Column (unpersisted):
ALTER TABLE MyTable
ADD newColumn DatatypeOfPersistedColumn
UPDATE myTable
SET newColumn = PersistedColumn
-- Delete the persisted column
ALTER TABLE MyTable
DROP COLUMN PersistedColumn
-- Rename the new column to the old name
EXEC sp_rename 'MyTable.newColumn', 'PersistedColumn', 'COLUMN'
#Mitch Wheat's solution works great. However, occasionally this will throw an error with 'Invalid Column name: newColumn' because the table has not been updated before it tries to run the update.
To fix this, add a GO statement to separate the two into batches:
-- Create a new Column (unpersisted):
ALTER TABLE MyTable
ADD newColumn DatatypeOfPersistedColumn
GO
UPDATE myTable
SET newColumn = PersistedColumn
-- Delete the persisted column
ALTER TABLE MyTable
DROP COLUMN PersistedColumn
-- Rename new column to old name
EXEC sp_rename 'MyTable.newColumn', 'PersistedColumn', 'COLUMN'
Assuming that the reason for converting the computed column into a "real" column is that you want to keep the existing values/functionality, but add the ability to override it where desired, you could add a new column (to be populated only where the existing derived value is to be overridden), and change the definition of the computed column to be COALESCE(NewColumn, Old Calculation Definition ) .
Just remove the formula from "Computed Column Specifications" in desing mode of the table in SSMS. The values will stay in column as it is.
Related
I already created table in database. Now, I need to add "Identity" Column. Please suggest.
Create Cus(id int Pk,Name varchar2(50),Age int);
insert into Cus(id,Name,Age) values (1,'abc',12);
// here i need to add "Identity"
alter table Cus alter column id Identity(1,1)
You cannot use Alter command to add an identity to the table.
Here, you need to create dummy column and drop existing one.
Create table Cus(id int ,[Name] varchar(50),Age int);
insert into Cus(id,[Name],Age) values (1,'abc',12);
Alter Table Cus Add dummyid int identity(1,1)
Alter Table Cus Drop Column id
Exec sp_rename 'Cus.dummyid ', 'id', 'Column'
No you cannot make any column identity after creating from the query.
You have 2 options, either make it from SQL Management Studio or Create another column and copy with identity .
From Management Studio.
Step 1: Select Table design.
Step 2: Change Column properties.
Step 3: Save
Or
You need to create new column with identity.
Create column with identity `Alter table Tablename add newcol int identity(1,1)
Then copy your data from previous column to this column by setting Identity_Insert ON.
Then drop your previous column.
After that change column name by using sp_rename.
Note: But this will change the ordinal position of your column.
ANOTHER OPTION
Create new table with similar structure just make your column
identity whichever you want to be.
Copy data from your old table to new table.
Drop old table.
Change name of new table with old table.
Edit:
For case of Foreign Key relationship
If they are not so many and feasible, then you may drop the constraint.
ALTER TABLE Yourtable
DROP FOREIGN KEY FK_PersonOrder;
Then follow the above steps and recreate them at the last.
ALTER TABLE Yourtable
ADD FOREIGN KEY (yourid) REFERENCES Persons(PersonID);
Finally i got Solution,
I added new column in 'Cus' table.
alter table Cus add tempCusId int identity;
i removed FK relation in User's Table
and i updated identity values in User Table
update user set id=1 where id= 1;
I Compared Id and TempCusId. After update I removed "Pk" relation in Cus table droped Column "Id",i made "TempCusId" as a "Pk" and identity. Finally User table it self "Id" Column I made FK relation.
And if u have multiple values there than go for a "While" loop
DECLARE #NumberofRowint int=30;
DECLARE #inirow INT=23;
Declare #Grade int ;
WHILE #inirow<= #NumberofRow
BEGIN
DECLARE #ProductID INT=(select Id from [Cus] where id=#inirow)
Set #Grade=(select id from Cus where id=#ProductID)
IF(#Grade= #inirow)
BEGIN
updatetbl_Users set Id=#inirow where id=#ProductID
END
SET #inirow = #inirow + 1;
END;
I tried below in sql server management, in a single query.
alter table add column amount2
update table set amount2=amount
I am getting column amount2 not found.
Can anyone tell me why this error?
That is not valid syntax (misses table name and column datatype) but in management studio use the batch separator GO between adding a column to an existing table and statements referencing the new column anyway.
Or alternatively you can use EXEC to execute it in a child batch.
SQL Server tries to compile all statements in the batch before execution and this will fail when it encounters the statement using this column.
There's a couple things wrong here.
The correct syntax for adding a column is MSDN - ALTER TABLE
ALTER TABLE [TableName] ADD [ColumnNAME] [DataType]
'Table' is a Reserved Keyword in SQL Server, although it is possible to have a table named 'Table'. You need to include brackets when referencing it.
SELECT * FROM [Table]
All together, you need
ALTER TABLE [Table] ADD [Amount2] INT
GO -- See Martin's answer for reason why 'GO' is needed here
UPDATE [Table] SET [Amount2] = [Amount]
You can get around this problem like this:
-- Alter the table and add new column "NewColumn"
ALTER TABLE [MyTable] ADD [NewColumn] CHAR(1) NULL;
-- Set the value of NewColumn
EXEC ('UPDATE [MyTable] SET [NewColumn] = ''A'' ');
Can the datatype of a field be changed to int from nvarchar??
alter table employee alter column designation int
is this valid?? If not can it be done in some other way??
P.S: I am using MS SQL Server
You can try doing an alter table. If it fails do this:
Create a new column that's an integer:
ALTER TABLE tableName ADD newCol int;
Select the data from the old column into the new one:
UPDATE tableName SET newCol = CAST(oldCol AS int);
Drop the old column
It is possible only when you column has no value or blank. If your column has some value which have nvarchar value and you should try to convert it into int, it will give error.
ALTER TABLE [table_name] ALTER COLUMN [column_name] [data_type]
Add new numeric column.
Copy from old char column to new column with trim and conversion.
Drop old char column.
Rename numeric column to old column name.
This worked for me (with decimals but I suppose it will work with ints):
alter table MyTable add MyColNum decimal(15,2) null
go
update MyTable set MyColNum=CONVERT(decimal(15,2), REPLACE(LTRIM(RTRIM(MyOldCol)), ',', '.')) where ISNUMERIC(MyOldCol)=1
go
alter table MyTable drop column MyOldCol
go
EXEC sp_rename 'MyTable.MyColNum', 'MyOldCol', 'COLUMN'
go
Can be done even simpler in just 2 steps
Update the column and set all non numberic values to null so alter won't fail.
Alter the table and set the type to int.
UPDATE employee
SET designation = (CASE WHEN ISNUMERIC(designation)=1 THEN CAST(CAST(designation AS FLOAT) AS INT)END )
ALTER TABLE employee
ALTER COLUMN designation INT
This takes the assumption that that the columns allow nulls. If not then that needs to be handled as well. For example: By altering the column to allow null, then after it has been converted to int then set all null values to 0 and alter the table to not allow null
Create a temp column
ALTER TABLE MYTABLE ADD MYNEWCOLUMN NUMBER(20,0) NULL;
Copy and casts the data from the old column to the new one
UPDATE MYTABLE SET MYNEWCOLUMN=CAST(MYOLDCOLUMN AS NUMBER(20,0));
Delete the old column
ALTER TABLE MYTABLE DROP COLUMN MYOLDCOLUMN;
Rename the new one to match the same name as the old one.
ALTER TABLE MYTABLE RENAME COLUMN MYNEWCOLUMN TO MYOLDCOLUMN;
Can you try this ?
alter table MyTable add MyColNum Varchar(500) null;
alter table MyTable add MyColNum int null;
I have a table in MSSQL server 2008. I would like to change one of the column in that table to computed column. Could somebody tell me how do I do that ?
Preserve the old data:
EXEC sp_rename 'MyTable.OldCol', 'RenamedOldCol', 'COLUMN';
Add computed column
ALTER TABLE MyTable ADD ComputedCol AS (some expression);
Then, when you're happy
ALTER TABLE MyTable DROP COLUMN RenamedOldCol;
How to remove a column from an existing table?
I have a table MEN with Fname and Lname
I need to remove the Lname
How to do it?
ALTER TABLE MEN DROP COLUMN Lname
Generic:
ALTER TABLE table_name DROP COLUMN column_name;
In your case:
ALTER TABLE MEN DROP COLUMN Lname;
Your example is simple and doesn’t require any additional table changes but generally speaking this is not so trivial.
If this column is referenced by other tables then you need to figure out what to do with other tables/columns. One option is to remove foreign keys and keep referenced data in other tables.
Another option is to find all referencing columns and remove them as well if they are not needed any longer.
In such cases the real challenge is finding all foreign keys. You can do this by querying system tables or using third party tools such as ApexSQL Search (free) or Red Gate Dependency tracker (premium but more features). There a whole thread on foreign keys here
This is the correct answer:
ALTER TABLE MEN DROP COLUMN Lname
But... if a CONSTRAINT exists on the COLUMN, then you must DROP the CONSTRAINT first, then you will be able to DROP the COLUMN. In order to drop a CONSTRAINT, run:
ALTER TABLE MEN DROP CONSTRAINT {constraint_name_on_column_Lname}
In SQL Server 2016 you can use new DIE statements.
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
The above query is re-runnable it drops the column only if it exists in the table else it will not throw error.
Instead of using big IF wrappers to check the existence of column before dropping it you can just run the above DDL statement
The question is, can you only delete a column from an unexisting table ;-)
BEGIN TRANSACTION
IF exists (SELECT * FROM sys.columns c
INNER JOIN sys.objects t ON (c.[object_id] = t.[object_id])
WHERE t.[object_id] = OBJECT_ID(N'[dbo].[MyTable]')
AND c.[name] = 'ColumnName')
BEGIN TRY
ALTER TABLE [dbo].[MyTable] DROP COLUMN ColumnName
END TRY
BEGIN CATCH
print 'FAILED!'
END CATCH
ELSE
BEGIN
SELECT ERROR_NUMBER() AS ErrorNumber;
print 'NO TABLE OR COLUMN FOUND !'
END
COMMIT
The simple answer to this is to use this:
ALTER TABLE MEN DROP COLUMN Lname;
More than one column can be specified like this:
ALTER TABLE MEN DROP COLUMN Lname, secondcol, thirdcol;
From SQL Server 2016 it is also possible to only drop the column only if it exists. This stops you getting an error when the column doesn't exist which is something you probably don't care about.
ALTER TABLE MEN DROP COLUMN IF EXISTS Lname;
There are some prerequisites to dropping columns. The columns dropped can't be:
Used by an Index
Used by CHECK, FOREIGN KEY, UNIQUE, or PRIMARY KEY constraints
Associated with a DEFAULT
Bound to a rule
If any of the above are true you need to drop those associations first.
Also, it should be noted, that dropping a column does not reclaim the space from the hard disk until the table's clustered index is rebuilt. As such it is often a good idea to follow the above with a table rebuild command like this:
ALTER TABLE MEN REBUILD;
Finally as some have said this can be slow and will probably lock the table for the duration. It is possible to create a new table with the desired structure and then rename like this:
SELECT
Fname
-- Note LName the column not wanted is not selected
INTO
new_MEN
FROM
MEN;
EXEC sp_rename 'MEN', 'old_MEN';
EXEC sp_rename 'new_MEN', 'MEN';
DROP TABLE old_MEN;
But be warned there is a window for data loss of inserted rows here between the first select and the last rename command.
To add columns in existing table:
ALTER TABLE table_name
ADD
column_name DATATYPE NULL
To delete columns in existing table:
ALTER TABLE table_name
DROP COLUMN column_name
This can also be done through the SSMS GUI. The nice thing about this method is it warns you if there are any relationships on that column and can also automatically delete those as well.
Put table in Design view (right click on table) like so:
Right click on column in table's Design view and click "Delete
Column"
As I stated before, if there are any relationships that would also need to be deleted, it will ask you at this point if you would like to delete those as well. You will likely need to do so to delete the column.
If you are using C# and the Identity column is int, create a new instance of int without providing any value to it.It worked for me.
[identity_column] = new int()
Syntax:
ALTER TABLE TABLE_NAME DROP COLUMN COLUMN_NAME;
For Example:
alter table Employee drop column address;