SQL. Changes require the table to be recreated - sql-server

There is a table full which contains data. Is it possible to change field from [not null] to [null] without dropping and recreating it?
SQL writes that table have to be dropped and recreated. :)

You can try:
alter table YourTable alter column YourColumn int null
Per Martin Smiths comment, a change in nullability does not require a copy of the table. On disk, each row has a nullabiltiy bitmap at the start. I thought the bitmap had to be resized in some cases, but apparently it contains a bit for each column, nullable or not nullable.

Have you tried to use ALTER TABLE XXX ALTER COLUMN YYY YOURTYPE NULL command?

This might help:
ALTER TABLE [Table] ALTER COLUMN [Column] [YourDataType] NULL

Related

How to remove a column from an existing table?

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;

How to change column datatype in SQL Server database without losing data?

I have SQL Server database and I just realized that I can change the type of one of the columns from int to bool.
How can I do that without losing the data that is already entered into that table?
You can easily do this using the following command. Any value of 0 will be turned into a 0 (BIT = false), anything else will be turned into 1 (BIT = true).
ALTER TABLE dbo.YourTable
ALTER COLUMN YourColumnName BIT
The other option would be to create a new column of type BIT, fill it from the old column, and once you're done, drop the old column and rename the new one to the old name. That way, if something during the conversion goes wrong, you can always go back since you still have all the data..
ALTER TABLE tablename
ALTER COLUMN columnname columndatatype(size)
Note: if there is a size of columns, just write the size also.
If it is a valid change.
you can change the property.
Tools --> Options --> Designers --> Table and Database designers --> Uncheck --> Prevent saving changes that required table re-creation.
Now you can easily change the column name without recreating the table or losing u r records.
if you use T-SQL(MSSQL); you should try this script:
ALTER TABLE [Employee] ALTER COLUMN [Salary] NUMERIC(22,5)
if you use MySQL; you should try this script:
ALTER TABLE [Employee] MODIFY COLUMN [Salary] NUMERIC(22,5)
if you use Oracle; you should try this script:
ALTER TABLE [Employee] MODIFY [Salary] NUMERIC(22,5)
Why do you think you will lose data? Simply go into Management Studio and change the data type. If the existing value can be converted to bool (bit), it will do that. In other words, if "1" maps to true and "0" maps to false in your original field, you'll be fine.
Go to Tool-Option-designers-Table and Database designers and Uncheck Prevent saving option
for me , in sql server 2016, I do it like this
*To rename column Column1 to column2
EXEC sp_rename 'dbo.T_Table1.Column1', 'Column2', 'COLUMN'
*To modify column Type from string to int:( Please be sure that data are in the correct format)
ALTER TABLE dbo.T_Table1 ALTER COLUMN Column2 int;
Alter column data type with check type of column :
IF EXISTS(
SELECT 1
FROM sys.columns
WHERE NAME = 'YourColumnName'
AND [object_id] = OBJECT_ID('dbo.YourTable')
AND TYPE_NAME(system_type_id) = 'int'
)
ALTER TABLE dbo.YourTable ALTER COLUMN YourColumnName BIT
In compact edition will take size automatically for datetime data type i.e. (8) so no need to set size of field and generate error for this operation...
I can modify the table field's datatype, with these following query: and also in the Oracle DB,
ALTER TABLE table_name
MODIFY column_name datatype;
Replace datatype without losing data
alter table tablename modify columnn newdatatype(size);

Altering a column: null to not null

I have a table that has several nullable integer columns. This is undesirable for several reasons, so I am looking to update all nulls to 0 and then set these columns to NOT NULL. Aside from changing nulls to 0, data must be preserved.
I am looking for the specific SQL syntax to alter a column (call it ColumnA) to "not null". Assume the data has been updated to not contain nulls.
Using SQL server 2000.
First, make all current NULL values disappear:
UPDATE [Table] SET [Column]=0 WHERE [Column] IS NULL
Then, update the table definition to disallow "NULLs":
ALTER TABLE [Table] ALTER COLUMN [Column] INTEGER NOT NULL
I had the same problem, but the field used to default to null, and now I want to default it to 0. That required adding one more line after mdb's solution:
ALTER TABLE [Table] ADD CONSTRAINT [Constraint] DEFAULT 0 FOR [Column];
You will have to do it in two steps:
Update the table so that there are no nulls in the column.
UPDATE MyTable SET MyNullableColumn = 0
WHERE MyNullableColumn IS NULL
Alter the table to change the property of the column
ALTER TABLE MyTable
ALTER COLUMN MyNullableColumn MyNullableColumnDatatype NOT NULL
For Oracle 11g, I was able to change the column attribute as follows:
ALTER TABLE tablename MODIFY columnname datatype NOT NULL;
Otherwise abatichev's answer seemed good. You can't repeat the alter - it complains (at least in SQL Developer) that the column is already not null.
this worked for me:
ALTER TABLE [Table]
Alter COLUMN [Column] VARCHAR(50) not null;
As long as the column is not a unique identifier
UPDATE table set columnName = 0 where columnName is null
Then
Alter the table and set the field to non null and specify a default value of 0
In case of FOREIGN KEY CONSTRAINT... there will be a problem if '0' is not present in the column of Primary key table. The solution for that is...
STEP1:
Disable all the constraints using this code :
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
STEP2:
RUN UPDATE COMMAND (as mentioned in above comments)
RUN ALTER COMMAND (as mentioned in above comments)
STEP3:
Enable all the constraints using this code :
exec sp_msforeachtable #command1="print '?'", #command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
this seems simpler, but only works on Oracle:
ALTER TABLE [Table]
ALTER [Column] NUMBER DEFAULT 0 NOT NULL;
in addition, with this, you can also add columns, not just alter it.
It updates to the default value (0) in this example, if the value was null.
In my case I had difficulties with the posted answers. I ended up using the following:
ALTER TABLE table_name CHANGE COLUMN column_name column_name VARCHAR(200) NOT NULL DEFAULT '';
Change VARCHAR(200) to your datatype, and optionally change the default value.
If you don't have a default value you're going to have a problem making this change, as default would be null creating a conflict.
Making column not null and adding default can also be done in the SSMS GUI.
As others have already stated, you can't set "not null" until all
the existing data is "not null" like so:
UPDATE myTable SET myColumn = 0
Once that's done, with the table in design view (right click on
table and click "design view"), you can just uncheck the Allow
Nulls columns like so:
Still in design view with the column selected, you can see the
Column Properties in the window below and set the default to 0 in there as well like so:
Let's take an example:
TABLE NAME=EMPLOYEE
And I want to change the column EMPLOYEE_NAME to NOT NULL. This query can be used for the task:
ALTER TABLE EMPLOYEE MODIFY EMPLOYEE.EMPLOYEE_NAME datatype NOT NULL;
For the inbuilt javaDB included in the JDK (Oracle's supported distribution of the Apache Derby) the below worked for me
alter table [table name] alter column [column name] not null;
You can change the definition of existing DB column using following sql.
ALTER TABLE mytable modify mycolumn datatype NOT NULL;
First make sure the column that your changing to not does not have null values
select count(*) from table where column's_name is null
Impute the missing values. you can replace the nulls with empty string or 0 or an average or median value or an interpolated value. It depends on your back fill strategy or forward fill strategy.
Decide if the column values need to be unique or non-unique. if they need to be unique than add an unique constraint. Otherwise, see if performance is adequate or if you need to add an index.

How to change the data type of a column without dropping the column with query?

I have a column which has a datatype : datetime. But now i want to convert it to datatype varchar. Can i alter the datatype without droppping the column? If yes, then please explain how?
MSDN says
ALTER TABLE mytable ALTER COLUMN mycolumn newtype
Beware of the limitations of the ALTER COLUMN clause listed in the article
If ALTER COLUMN doesn't work.
It is not unusual for alter column to fail because it cannot make the transformation you desire. In this case, the solution is to create a dummy table TableName_tmp, copy the data over with your specialized transformation in the bulk Insert command, drop the original table, and rename the tmp table to the original table's name. You'll have to drop and recreate the Foreign key constraints and, for performance, you'll probably want to create keys after filling the tmp table.
Sound like a lot of work? Actually, it isn't.
If you are using SQL Server, you can make the SQL Server Management Studio do the work for you!
Bring up your table structure (right-click on the table column and select "Modify")
Make all of your changes (if the column transformation is illegal, just add your new column - you'll patch it up in a moment).
Right-click on the background of the Modify window and select "Generate Change Script." In the window that appears, you can copy the change script to the clipboard.
Cancel the Modify (you'll want to test your script, after all) and then paste the script into a new query window.
Modify as necessary (e.g. add your transformation while removing the field from the tmp table declaration) and you now have the script necessary to make your transformation.
ALTER TABLE [table name] MODIFY COLUMN [column name] datatype
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20)
Type the below query:
alter table table_Name alter column column_name datatype
e.g.
alter table Message alter column message nvarchar(1024);
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20)
With SQL server 2008 and more, using this query:
ALTER TABLE [RecipeInventorys] ALTER COLUMN [RecipeName] varchar(550)
This work for postgresql 9.0.3
alter table [table name] ALTER COLUMN [column name] TYPE [character varying];
http://www.postgresql.org/docs/8.0/static/sql-altertable.html
ALTER TABLE [table_name] ALTER COLUMN [column_name] varchar(150)
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20) this is perfect for change to datatype
ORACLE - Alter table table_name modify(column_name new_DataType);
ALTER TABLE yourtable MODIFY COLUMN yourcolumn datatype
ALTER TABLE table_name
MODIFY (column_name data_type);
ALTER tablename MODIFY columnName newColumnType
I'm not sure how it will handle the change from datetime to varchar though, so you may need to rename the column, add a new one with the old name and the correct data type (varchar) and then write an update query to populate the new column from the old.
http://www.1keydata.com/sql/sql-alter-table.html
alter table [table name] remove [present column name] to [new column name.

Force default value when adding column to table - SQL Server

In SQL Server 2000/2005,
Is it possible to force the default value to be written to already existing rows when adding a new column to a table without using NOT NULL on the new column?
You need two statements. First create the column with not null. Then change the not null constraint to nullable
alter table mytable add mycolumn varchar(10) not null default ('a value')
alter table mytable alter column mycolumn varchar(10) null
I understand your question, but you are saying that for future records, NULL (unknown, indeterminate or whatever your semantics are) is acceptable (but if it is left off in an insert, there will be a default), but that for all the existing data, you are going to go ahead and assign it the default.
I would have to look hard at this situation and ask why you are even going to allow NULLs in future records at all - given none of the historical records will have it, and there is a default in place for future records.
I doubt it.
http://msdn.microsoft.com/en-us/library/ms190273(SQL.90).aspx
The approach recommended by Microsoft is as follows (taken from the url above)
UPDATE MyTable SET NullCol = N'some_value' WHERE NullCol IS NULL
ALTER TABLE MyTable ALTER COLUMN NullCOl NVARCHAR(20) NOT NULL
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
[**WITH VALUES]**
WITH VALUES can be used to store the default value in the new column for each existing row in the table.
more detail on MSDN link .
https://msdn.microsoft.com/en-in/library/ms190273.aspx

Resources