2009-02-23 31 views
24

Şu anda varchar türünde bir veritabanında iki sütun var (16). Şey, sayıları içerir ve her zaman sayıları içerecektir. Bu nedenle, türünü tamsayı olarak değiştirmek istiyoruz. Ama sorun şu ki elbette zaten veri içeriyor.Varchar'dan sayıya sahip bir sütunun türünü int

Bu sütunun türünü varchar'dan int'ye değiştirebilmemizin ve orada bulunan tüm sayıları kaybetmemenin bir yolu var mı? Umarım bir çeşit sql, sadece geçici kolonlar oluşturmaya ve C# programına veya dönüştürme yapmak için bir şey oluşturmaya gerek kalmadan sadece koşabiliriz. SQL Server'ın dizeleri dönüştürmek için bazı işlevleri varsa oldukça kolay olabilir Sayılar, ancak ben SQL'de çok kararsızım. Hemen hemen sadece C# ile çalışır ve veritabanına LINQ'dan SQL'e erişir.

Not: Evet, sütunu ilk etapta bir varchar yapmak çok iyi bir fikir değildi, ama maalesef yaptıkları gibi.

cevap

30

bu geçici bir tablo kullanıyor olacaktır, ancak çok sql olmayacaktır yapmak için tek güvenilir yolu:

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 
+0

#tmp bir tmp tablonun rastgele adıdır? – Svish

+1

İyi cevap - select döküm (int olarak silly_column), herhangi bir dönüşüm sorunları yok emin olmak için bad_table den other_columns ve onlar aslında ints tüm vardır - bu ilk aday olacağını. – brendan

+3

Yaptığım tüm isimlerden #tmp ile ilgili bir not yaptın mı? – cjk

8

Sadece yönetim stüdyoda veri türünü değiştirmek

(gitmek gerekebilir Araçlar> Seçenekler> Tasarımcılar'a geçin ve tabloyu yeniden oluşturan değişiklikleri kaydetmeyi engelleyen seçeneği devre dışı bırakın)

+0

tüm değerleri kaybedersiniz sonra ?? – Svish

+0

Hayır. İsterseniz bir test masasında deneyin? – ctrlalt3nd

+0

Bunu daha yeni yaptım ve mükemmel bir şekilde çalıştı. Önce var olan tüm değerlerin dize türünde sayılar olup olmadığını ve tüm varcharları sayısal türlere başarıyla dönüştürebildiğimi kontrol ettim. Sütuna (Dizinler, Tuşlar, Tetikleyiciler, ...) tüm referansları devre dışı bıraktıktan sonra devam ettim ve MSSMS'deki değişikliği başlattım. Harika! – Rynkadink

1

Önceki yanıtları kesinlikle takdir ediyorum ama aynı zamanda daha eksiksiz bir cevabın diğer araştırmacılar için yararlı olacağını düşündüm ...

Üretim türü tablosunda değişiklik yaparsanız, yardımcı olabilecek birkaç uyarı vardır. Tabloda üzerinde tanımlı bir kimlik sütunu varsa

  1. verilerin yeniden tak etrafında açılıp IDENTITY_INSERT ayarlamak zorunda kalacaktır. Ayrıca açık bir sütun listesi kullanmanız gerekecektir. Eğer veritabanında verileri öldürme kalmamayı garantilemek truncate etrafında TRANSACTIONS kullanmak istiyorsanız o zaman sadece SQ Server Management Studio'da değişiklik yapmaya çalışıyorum, çok fazla veri varsa
  2. /işlemini
  3. takın/değiştirmek zaman aşımı ile başarısız olabilir ve verileri kaybedebilirsiniz.

, @cjk verdi cevabını genişletmek bakmak için aşağıdaki:

Not: 'tuc' başlayacak gerçek tabloismi için bu komut yalnızca bir yer tutucudur işleme başlamak deneyin

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 
18

bunu yapmanın en kolay yoludur:

alter table myTable alter column vColumn int; 

Bu lon olarak çalışacak tüm veriler bir int

  • içine uyacak

    1. olarak gr tüm verileri int dönüştürülebilir (yani "araba" değeri başarısız olur.
    2. vColumn'u içeren dizin yok.İndeksler varsa, bir damla eklemeniz ve bulunduğunuz yere geri dönmeleri için oluşturmanız gerekir.
  • +2

    @svish çalıştı: Gerçekten "araba" değil 'karakter' olmak istemiştin. – jmoreno

    +0

    Oh! Afedersiniz. Şimdi ne anlama geldiğini anlayın, hehe :) – Svish

    +0

    bu bir muamele yaptı. Yönetim stüdyosunda çalışırken başarısız oldu – PowerMan2015

    İlgili konular