web-dev-qa-db-ja.com

1つ以上のオブジェクトがこの列にアクセスするため、ALTER TABLE DROP COLUMNが失敗しました

私はこれをやろうとしています:

ALTER TABLE CompanyTransactions DROP COLUMN Created

しかし、私はこれを取得します:

メッセージ5074、レベル16、状態1、行2オブジェクト「DF__CompanyTr__Creat__0CDAE408」は列「作成済み」に依存しています。メッセージ4922、レベル16、状態9、行2 ALTER TABLE DROP COLUMN 1つ以上のオブジェクトがこの列にアクセスするため、作成に失敗しました。

これは最初のコード表です。どういうわけか、移行がすべて台無しになり、変更を手動でロールバックしようとしています。

私はnoこれが何であるかを考えています:

DF__CompanyTr__Creat__0CDAE408
41
Casey Crookston

列を削除する前に、列からconstraintsを削除する必要があります。参照している名前はdefault constraintです。

例えば.

alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];
alter table CompanyTransactions drop column [Created];
80
SqlZim

@SqlZimの答えは正しいですが、なぜこれが発生したのかを説明するだけです。私は同様の問題を抱えていましたが、これは非常に無邪気なことによって引き起こされました:列にデフォルト値を追加する

ALTER TABLE MySchema.MyTable ADD 
  MyColumn int DEFAULT NULL;

ただし、MS SQL Serverの領域では、列のデフォルト値はCONSTRAINTです。また、すべての制約と同様に、識別子があります。また、CONSTRAINTで使用されている列は削除できません。

したがって、この種の問題を実際に回避できるのは、常にデフォルトの制約に明示的な名前を与えることです。次に例を示します。

ALTER TABLE MySchema.MyTable ADD 
  MyColumn int NULL,
  CONSTRAINT DF_MyTable_MyColumn DEFAULT NULL FOR MyColumn;

列をドロップする前に制約をドロップする必要がありますが、少なくともその名前を前もって知っているです。

14
malloc4k

すでに回答に書かれているように、削除しようとしているすべての列に関連する制約(SQLによって自動的に作成される)をドロップする必要があります。

必要なことを行うには、次の手順を実行します。

  1. sp_helpconstraintを使用してすべての制約の名前を取得します。これはシステムストアドプロシージャユーティリティです。次のexec sp_helpconstraint '<your table name>'を実行します
  2. 制約の名前を取得したら、その制約名をコピーし、次のステートメント、つまりalter table <your_table_name> drop constraint <constraint_name_that_you_copied_in_1>を実行します(このような形式または類似の形式になります)
  3. 制約を削除したら、従来の方法、つまりAlter table <YourTableName> Drop column column1, column2などを使用して1つ以上の列を削除できます。
3
vibs2006

datatypeを変更するときは、すべてのデータベースのconstraint keyを変更する必要があります

  alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];
0
Jayant Wexoz

いくつかのことを行う必要があります。

  1. 最初に、制約が情報スキーマで終了するかどうかを確認する必要があります
  2. 列とdefault_constraintsが同じオブジェクトIDを持っている場合は、sys.default_constraintsとsys.columnsを結合して照会する必要があります
  3. ステップ2で結合すると、default_constraintsから制約名を取得します。その制約を削除します。ここに私がやったそのようなドロップの例があります。
-- 1. Remove constraint and drop column
IF EXISTS(SELECT *
          FROM INFORMATION_SCHEMA.COLUMNS
          WHERE TABLE_NAME = N'TABLE_NAME'
            AND COLUMN_NAME = N'LOWER_LIMIT')
   BEGIN
    DECLARE @sql NVARCHAR(MAX)
    WHILE 1=1
        BEGIN
            SELECT TOP 1 @sql = N'alter table [TABLE_NAME] drop constraint ['+dc.name+N']'
            FROM sys.default_constraints dc
            JOIN sys.columns c
            ON c.default_object_id = dc.object_id
            WHERE dc.parent_object_id = OBJECT_ID('[TABLE_NAME]') AND c.name = N'LOWER_LIMIT'
            IF @@ROWCOUNT = 0
                BEGIN
                    PRINT 'DELETED Constraint on column LOWER_LIMIT'
                    BREAK
                END
        EXEC (@sql)
    END;
    ALTER TABLE TABLE_NAME DROP COLUMN LOWER_LIMIT;
    PRINT 'DELETED column LOWER_LIMIT'
   END
ELSE
   PRINT 'Column LOWER_LIMIT does not exist'
GO
0
Akash Yellappa