NOTE: The following is an undocumented method which requires the direct update of the system table 'syscolumns'. All the usual disclaimers about "you are on your own if you screw this up" apply.
Yet another option you have available to you ... requires directly updating the syscolumns table and bouncing the dataserver. [Definitely something you should test before implementing in production.]
First some background:
Different datatypes require different numbers of bytes for actual storage. When accessing a data record the dataserver will use the contents of syscolumns to determine the offsets/lengths when parsing the string of bytes that make up the data record on a data page.
Let's see how many bytes are required for various numeric(#) columns ...
===========================
create table t1
(a numeric(10) -- same as your identity column
,b numeric(11)
,c numeric(12)
,d numeric(13))
go
sp_help t1
go
Name Owner Object_type Object_status
---- ----- ----------- --------------
t1 dbo user table keep first tex
(1 row affected)
Column_name Type Length Prec Scale
----------- ------- ------ ---- -----
a numeric 6 10 0
b numeric 6 11 0
c numeric 6 12 0
d numeric 7 13 0
===========================
Your current numeric(10)/identity column has a length of 6 (ie, requires 6 bytes).
From the t1 table we see that columns a/b/c, configured to use numeric(10/11/12) respectively, all have a length of 6 (ie, all require 6 bytes). What this tells us is that you could define a column as numeric(10), numeric(11) or numeric(12) and you would end up using the same amount of storage space (ie, 6 bytes). And it's this bit of info we can use to extend the size of your identity column.
Example:
In the following example I create a table with a numeric(10) column as the identity, insert a couple records, and show what happens if I try to set the 'next' ident value > 9,999,999,999 ...
===========================
create table t1
(a numeric(10) identity
,b varchar(30))
go
insert t1 (b) values ('a')
go
sp_chgattribute t1,'identity_burn_max',0,'9000000000'
go
insert t1 (b) values ('x')
go
select * from t1
go
a b
------------- -
1 a
9000000001 x
-- try to set next ident to 10,000,000,000 (a numeric(11) value):
sp_chgattribute t1,'identity_burn_max',0,'10000000000'
go
Msg 12972, Level 16, State 1:
Server 'AIM1', Procedure 'sp_chgattribute', Line 1016:
Identity value '10000000000' overflow for table 't1'.
===========================
As expected, I can't set the 'next' ident to a value that does not fit within a numeric(10) column.
Since numeric(10) and numeric(12) require the same number of bytes for storage, we should be able to modify the ident column to use numeric(12) without requiring any additional space.
While we could trying using the alter tablecommand to change the ident column's datatype, this would require a datacopy of the entire table (basically the same thing that will occur for your select/into option).
The other option is to directly modify the syscolumns record for our ident column to change the precision from 10 to 12. (Since numeric(10) and numeric(12) use the same number of bytes, we should be able to update syscolumns with no concern about corrupting the logic used to parse the string of bytes that make up the data record on a data page.)
===========================
sp_configure 'allow updates',1
go
begin tran
update syscolumns set prec = 12
where id = object_id('t1')
and name = 'a'
go
-- verify 1 row updated and prec = 12
-- if good then
commit tran
-- else
-- rollback tran
go
shutdown
go
-- restart dataserver
1> sp_help t1
2> go
Name Owner Object_type Object_status
---- ----- ----------- --------------
t1 dbo user table keep first tex
(1 row affected)
Column_name Type Length Prec Scale
----------- ------- ------ ---- -----
a numeric 6 12 0
b varchar 30 NULL NULL
sp_chgattribute t1,'identity_burn_max',0,'10000000000'
go
DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
'identity_burn_max' attribute of object 't1' changed to 10000000000.
insert t1 (b) values ('z')
go
select * from t1
go
a b
--------------- -
1 a
9000000001 x
10000000001 z
===========================
Because I didn't increase the length (ie, # of storage bytes) for the ident column, I should able to safely access old rows because the offsets/lengths used for parsing the string of bytes that make up the data record haven't changed.
===========================
select * from t1 where a = 1
go
a b
--------------- ------------------------------
1 a
update t1 set b = 'zzz' where a = 1
go
select * from t1
go
a b
--------------- ---
1 zzz
9000000001 x
10000000001 z
===========================