😃

SQLServerでデフォルト値が設定されているカラムの定義を変更する際の注意点

2024/10/08に公開

みなさんは、SQLServerを使用したことはありますか?

私は現在働いている会社で使うようになり半年程が経ちました!
(一生使うことないだろと思っていました。。)

最近、DBにテーブル追加をしたり定義を変更することが多くなり、その中で躓いたポイントを備忘録として残したいと思い、記事を書くに至りました!

なぜ削除できないのか?

https://learn.microsoft.com/ja-jp/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver16&redirectedfrom=MSDN#column-column_name:~:text=できません。-,COLUMN column_name,-テーブルから constraint_name

上記、公式サイトにも記載されています。

  • キー列または INCLUDE としてインデックスで使用されている列
  • CHECK、FOREIGN KEY、UNIQUE、または PRIMARY KEY 制約で使用されている列
  • DEFAULT キーワードを使って定義された既定値に関連付けられている、または既定値のオブジェクトにバインドされている。
  • ルールにバインドされます。

MySQLなどではDefault値を気ににすることなくカラムの削除が行えましたが、
SQL Serverでは制約として認識されるみたいで、カラムの属性を修正するときや削除するときにはDefault値が設定されているかを確認しておく必要があります!

どうやって消すの?

以下のようなカラムがあったとします。

ALTER TABLE sample_table ADD sample_name nvarchar(100) NOT NULL DEFAULT "";

nvarchar(200)にも変更してみます!

ALTER TABLE sample_table
ALTER COLUMN sample_name nvarchar(200) NOT NULL DEFAULT "";

上記SQLを実行するとエラーが発生するかと思います。

The object '<default constraint name>' is dependent on column 'sample_name'. 2) [Code: 4922, SQL State: S1000] "" failed because one or more objects access this column.

SQL Serverの仕様を知らずにこのエラーを見るとなんで??ってなりますが、
落ち着いてGoogle等で検索してみるとそれっぽい記事が見つかります!

-- nvarchar(200)は制約名を格納するために記載しています
DECLARE @ConstraintName nvarchar(200)

-- DEFAULT制約の名称を取得し、@に代入しています。
SELECT @ConstraintName = obj.name
FROM sys.objects AS obj
JOIN sys.columns AS clm
    ON obj.object_id = clm.default_object_id
WHERE obj.type = 'D'
    AND obj.parent_object_id = OBJECT_ID('sample_table')
    AND clm.name = 'sanple_name'

-- 取得した結果からDefault制約を削除する
IF @ConstraintName IS NOT NULL
    EXEC('ALTER TABLE sample_table DROP CONSTRAINT ' + @ConstraintName)
GO

-- カラムのデータ型を変更する
ALTER TABLE sample_table
ALTER COLUMN sample_name nvarchar(200) NOT NULL DEFAULT "";
GO

上記SQL文を実行すると該当カラムのデータ型が変更されているかと思います!
カラムを削除する時も同様の手順で問題ないと思います。

SQLServerを使う現場というのもまだまだあるかなと思うので
このようなエラーで詰まった方の役に立てたら良いなと思います。

また、自分自身はこれからもSQL Serverと戦っていかなくてはならないので備忘録として残しておきたいと思いました!
こちらの記事を最後まで読んでいただいた方、ありがとうございます!
今後ともZennで少しずつ記事を書いていけたらいいなと考えています🙇

Discussion