2009-02-23 5 views
24

현재 varchar (16) 유형의 데이터베이스에 두 개의 열이 있습니다. 것은 숫자를 포함하며 항상 숫자를 포함합니다. 따라서 유형을 정수로 변경하려고합니다. 그러나 문제는 물론 그것이 이미 데이터를 포함하고 있다는 것입니다.숫자가있는 열의 유형을 varchar에서 int로 변경하십시오.

우리는 그 열의 유형을 varchar에서 int로 변경할 수 있으며 거기에 이미있는 모든 숫자를 잃지 않을 방법이 있습니까? 다행스럽게도 일종의 SQL을 임시 컬럼을 생성하지 않고도 C# 프로그램이나 변환 등을 할 필요없이 생성 할 수 있습니다. SQL Server에 문자열 변환을위한 몇 가지 기능이 있다면 매우 쉽습니다. 숫자,하지만 난 매우 불안정한 SQL에있어. 거의 C#에서만 작동하고 LINQ to SQL을 통해 데이터베이스에 액세스합니다.

참고 : 예, 처음부터 열을 varchar로 지정하는 것은 좋지 않았지만 불행히도 그 방법을 사용했습니다.

답변

30

이 임시 테이블을 사용하지만, 훨씬 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 
+0

#tmp는 tmp 테이블의 임의의 이름입니까? – Svish

+1

좋은 답변 - 나는이 첫 번째 선택 캐스팅 (silly_column int로), other_columns bad_table에서 에서 변환 문제가 있는지 확인하고 그들은 모두 사실 int입니다. – brendan

+3

내가 만든 모든 이름 중에서 #tmp에 대한 의견을 제출하셨습니까? – cjk

8

그냥 관리 스튜디오에서 데이터 유형을 변경

(당신은 갈 필요가 있습니다 도구> 옵션> 디자이너로 이동하여 테이블을 다시 만드는 변경 사항을 저장하지 못하도록하는 옵션을 해제하십시오)

+0

실 거예요 나는 모든 값을 잃지 않을거야 ?? – Svish

+0

아니요, 원하면 시험대에서 시험해보십시오. – ctrlalt3nd

+0

방금 ​​해봤는데 완벽하게 작동했습니다. 먼저 모든 기존 값이 문자열 유형에 저장된 숫자인지 확인하고 모든 varchars를 숫자 유형으로 변환 할 수 있는지 확인했습니다. 열 (인덱스, 키, 트리거 ...)에 대한 모든 참조를 비활성화 한 후 MSSMS에서 변경 사항을 적용했습니다. 좋아요! – Rynkadink

1

나는 이전 답변에 감사 할뿐 아니라보다 완벽한 답변이 다른 검색 자에게 도움이 될 것이라고 생각했습니다.

프로덕션 유형 테이블을 변경하는 경우 도움이되는 몇 가지주의 사항이 있습니다. 당신이 테이블에 정의 된 정체성 열이있는 경우

  1. 당신은 데이터의 재 삽입 주위에 끌 IDENTITY_INSERT을 설정해야합니다. 또한 명시 적 열 목록을 사용해야합니다. 당신이 데이터베이스에 데이터를 살해하지 확신 할 잘라야 주위 TRANSACTIONS을 사용할 경우 다음 단지 SQ Server Management Studio의 변화를 만들려고 노력, 많은 양의 데이터가있는 경우
  2. /공정을
  3. 를 다시 삽입/변경 시간 초과로 실패 할 수 있으며 데이터를 잃을 수 있습니다.

는 @cjk이 준 답을 확장 보는하려면 다음

참고 : 'TUC는' 시작 실제 TABLENAME이 스크립트에 단지 자리 표시 자입니다 트랜잭션을 시작 을 시도

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

이 작업을 수행하는 가장 쉬운 방법은 다음과 같습니다

alter table myTable alter column vColumn int; 

이 경도로 작동합니다 모든 데이터는 INT

  • 안에 들어가는

    1. g로서 모든 데이터가 int로 전환시킬 수있다 (즉, "car"값이 실패합니다)
    2. vColumn을 포함하는 인덱스가 없습니다.인덱스가있는 경우, 드롭을 포함 시켜서 인덱스를 만들면 원래 위치로 돌아갈 수 있습니다.
  • +2

    @svish : 정말 "차"가 아닌 "차"가되고 싶었습니다. – jmoreno

    +0

    오! 죄송합니다. 당신이 지금 그것을 의미하는 것을 이해하십시오, hehe :) – Svish

    +0

    이것은 치료를했습니다. 경영 스튜디오를 통해 시도 할 때 실패했습니다. – PowerMan2015

    관련 문제