We have two columns in a database which is currently of type varchar(16). Thing is, it contains numbers and always will contain numbers. We therefore want to change its type to integer. But the problem is that it of course already contains data.
Is there any way we can change the type of that column from varchar to int, and not lose all those numbers that are already in there? Hopefully some sort of sql we can just run, without having to create temporary columns and create a C# program or something to do the conversion and so forth... I imagine it could be pretty easy if SQL Server have some function for converting strings to numbers, but I am very unstable on SQL. Pretty much only work with C# and access the database through LINQ to SQL.
Note: Yes, making the column a varchar in the first place was not a very good idea, but that is unfortunately the way they did it.
SQL Server's CAST() and CONVERT() methods can be used to convert VARCHAR to INT.
To convert a varchar type to a numeric type, change the target type as numeric or BIGNUMERIC as shown in the example below: SELECT CAST('344' AS NUMERIC) AS NUMERIC; SELECT CAST('344' AS BIGNUMERIC) AS big_numeric; The queries above should return the specified value converted to numeric and big numeric.
The only reliable way to do this will be using a temporary table, but it will not be much SQL:
select * into #tmp from bad_table
truncate table bad_table
alter bad_table alter column silly_column int
insert bad_table
select cast(silly_column as int), other_columns
from #tmp
drop table #tmp
The easiest way to do this is:
alter table myTable alter column vColumn int;
This will work as long as
Just change the datatype in SQL Server Management Studio.
(You may need to go to menu Tools → Options → Designers, and disable the option that prevents saving changes that re-create the table.)
I totally appreciate the previous answers, but also thought a more complete answer would be helpful to other searchers...
There are a couple caveats that would be helpful if you making the changes on a production type table.
IDENTITY_INSERT
on and off around the re-insert of data. You will also have to use an explicit column list.TRANSACTIONS
around the truncate/alter/reinsert processTo expand the answer that @cjk gave, look at the following:
Note: 'tuc' is just a placeholder in this script for the real tablename
begin try
begin transaction
print 'Selecting Data...'
select * into #tmp_tuc from tuc
print 'Truncating Table...'
truncate table tuc
alter table tuc alter column {someColumnName} {someDataType} [not null]
... Repeat above until done
print 'Reinserting data...'
set identity_insert tuc on
insert tuc (
<Explicit column list (all columns in table)>
)
select
<Explicit column list (all columns in table - same order as above)>
from #tmp_tuc
set identity_insert tuc off
drop table #tmp_tuc
commit
print 'Successful!'
end try
begin catch
print 'Error - Rollback'
if @@trancount > 0
rollback
declare @ErrMsg nvarchar(4000), @ErrSeverity int
select @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY()
set identity_insert tuc off
RAISERROR(@ErrMsg, @ErrSeverity, 1)
end catch
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