web-dev-qa-db-ja.com

varcharからintへの数値を持つ列のタイプを変更します

現在、varchar(16)型のデータベースに2つの列があります。つまり、数字が含まれ、常に数字が含まれます。したがって、その型を整数に変更する必要があります。しかし、問題はもちろん、すでにデータが含まれていることです。

その列の型をvarcharからintに変更する方法はありますか?また、既にそこにあるすべての数値を失うことはありませんか?一時列を作成したり、C#プログラムなどを作成したりすることなく、何らかのSQLを実行できることを願っています。SQLServerに文字列を変換する機能があれば、かなり簡単になると思います数字ですが、私はvery SQLでは不安定です。ほとんどの場合、C#でのみ動作し、LINQ to SQLを介してデータベースにアクセスします。

注:はい、そもそもカラムをvarcharにすることはあまり良い考えではありませんでしたが、残念ながらそれは彼らのやり方です。

32
Svish

これを行う唯一の信頼できる方法は、一時テーブルを使用することですが、それほど多くの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
38
cjk

これを行う最も簡単な方法は次のとおりです。

alter table myTable alter column vColumn int;

これは、

  1. すべてのデータはint内に収まります
  2. すべてのデータをintに変換できます(つまり、「car」の値は失敗します)
  3. vColumnを含むインデックスはありません。インデックスがある場合は、ドロップして作成し、元の場所に戻るために作成する必要があります。
22
jmoreno

SQL Server Management Studioでデータ型を変更するだけです。

(メニューツールオプションデザイナーに移動し、テーブルを再作成する変更を保存できないオプションを無効にする必要がある場合があります。 )

7
ctrlalt3nd

私は以前の回答に完全に感謝しますが、より完全な回答が他の検索者にとっても役立つと考えました...

本番タイプのテーブルに変更を加える場合に役立ついくつかの注意事項があります。

  1. テーブルにidentity列が定義されている場合、データの再挿入の前後でIDENTITY_INSERTのオンとオフを設定する必要があります。また、明示的な列リストを使用する必要があります。
  2. データベース内のデータを強制終了しないようにするには、truncate/alter/reinsertプロセスの周りでTRANSACTIONSを使用します
  3. 大量のデータがある場合、SQ Server Management Studioで変更を行おうとするとタイムアウトで失敗し、データを失う可能性があります。

@cjkが与えた答えを展開するには、次を見てください。

注:「tuc」は、実際のテーブル名に対するこのスクリプトの単なるプレースホルダーです

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
1
scott-pascoe