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?
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.
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.
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.
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.
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With