Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change datatype of column with data

Tags:

sql

oracle

Let's say I have a table call_log that has a column named duration. Let's further pretend that when I put the table together, I made the mistake of making duration a varchar column instead of a number. Now I can't properly sort on that column. I want to rename the column so I issue...

ALTER TABLE call_log MODIFY (duration NUMBER);

But I get...

ORA-01439: column to be modified must be empty to change datatype.

My table has been in use and has data! And I don't want to lose the data. How do I modify the column's datatype without losing data?

like image 491
mason Avatar asked Apr 18 '14 14:04

mason


People also ask

Can we change the datatype of a column which has data?

We can use ALTER TABLE ALTER COLUMN statement to change the datatype of the column. The syntax to change the datatype of the column is the following. In the syntax, Tbl_name: Specify the table name that contains the column that you want to change.

Can we change the datatype of a column with data in SQL?

You can modify the data type of a column in SQL Server by using SQL Server Management Studio or Transact-SQL. Modifying the data type of a column that already contains data can result in the permanent loss of data when the existing data is converted to the new type.

Can we change the datatype of a column with data in Oracle?

You could do the following steps: Add the new column with a new name. Update the new column from old column. Drop the old column.


3 Answers

Create a temporary column with the correct data type, copy the data to the new column, drop the old column, rename the new column to match what the old column was named.

ALTER TABLE call_log ADD (duration_temp NUMBER);
UPDATE call_log SET duration_temp = duration;
ALTER TABLE call_log DROP COLUMN duration;
ALTER TABLE call_log RENAME COLUMN duration_temp TO duration;

The idea for this answer came from Oracle's forums.

like image 82
mason Avatar answered Oct 19 '22 20:10

mason


The best solution to preserve the original order of columns: create a temp column, copy the data to it, set the original column to null, modify its type, set the data from temp column back to it and drop the temp column:

ALTER TABLE call_log ADD duration_temp NUMBER;
UPDATE call_log SET duration_temp = duration;
UPDATE call_log SET duration = NULL;
ALTER TABLE call_log MODIFY duration NUMBER;
UPDATE call_log SET duration = duration_temp;
ALTER TABLE call_log DROP (duration_temp);
like image 34
Robert J Avatar answered Oct 19 '22 22:10

Robert J


the previous solution is excellent, however if you don't want to change the columns orders in call_log table structure, then the following steps are for this:

create table temp_call_log  as select * from call_log; /* temp backup table for call_log */
UPDATE call_log SET duration = null;
/*check,... be sure.... then commit*/
commit;
ALTER TABLE call_log MODIFY duration NUMBER;
UPDATE call_log c SET c.duration = (select t.duration from temp_call_log t where t.primarykey_comumn = c.primarykey_column);
/*check,... be sure.... then commit*/
commit;
drop table temp_call_log;

note1: change primarykey_comumn with primary key in table call_log.

note2: this solution assumes that your data size is not big.

like image 31
Eng. Samer T Avatar answered Oct 19 '22 21:10

Eng. Samer T