2017-05-03 14 views
1

一部のテーブルのID列にautoincrement(IDENTITY)プロパティを追加する必要があります。私は実際にID列を削除してからIDENTITY列として再度追加する必要があることを示すいくつかの研究を行ってきました。列にオートインクリメントを追加し、制約を処理する[SQL Server]

-The object 'FK_OTHER_TABLE_MY_ID' is dependent on column 'MY_ID'. (foreign key constraint apparently)

-The object 'IDX_PK_MY_TABLE' is dependent on column 'my_ID' (Primary key constraint).

は、だから、僕は(他のテーブルの外部キーと主キーで制約をドロップすることができます:私はIDの列を削除しようとすると、しかし、私は基本的に言って、エラー・メッセージのリストを取得します私のテーブル)し、それらを再び追加します。

もしそうなら

、一つだけで、エラーメッセージ1で定義された制約を落とす未満エラーが発生しやすくなり、私のID列を参照して、すべての外部キーのためにそれを行うための方法があります。

+0

ドロップ2つのFKS最初 – Sami

答えて

0

あなたがテーブルに基づいて、すべての外部キーを見つけるためにsp_fkeysを使用することができます。

EXEC sp_fkeys 'TableName' 

スクリプトを望むなら、あなたはこのような動的な何かを行うことができます。真ん中には、IDENTITYフィールドを変更するスクリプトを置くセクションがあります。

DECLARE @PKTableName VARCHAR(100), 
     @PKName varchar(100), 
     @FKName varchar(100), 
     @sql varchar(max), 
     @PKcolumnName varchar(30), 
     @FKtable VARCHAR(100), 
     @FKColumnName VARCHAR(100), 
     @parentColumnNumber int 

SET @PKTableName = 'YourTableName' 

IF OBJECT_ID('tempdb..#FKAgainstTableList') IS NOT NULL 
    DROP TABLE #FKAgainstTableList 
CREATE TABLE #FKAgainstTableList (FKTable varchar(100), FKName varchar(100), FKColumnName varchar(100)) 

IF OBJECT_ID('tempdb..#PKDetails') IS NOT NULL 
    DROP TABLE #PKDetails 
CREATE TABLE #PKDetails (PKName varchar(100), PKColumnName varchar(100), Ordinal_Position int) 

/* Let's gather details about our primary key */ 
INSERT INTO #PKDetails (PKName, PKColumnName, Ordinal_Position) 
SELECT 
    CONSTRAINT_NAME 
    ,COLUMN_NAME 
    ,ORDINAL_POSITION 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1 
    AND table_name = @PKTableName 

/* We need this when we're putting the FK's back on at the end */ 
SET @PKName = (SELECT DISTINCT PKName FROM #PKDetails) 
SELECT @PKcolumnName = COALESCE(@PKcolumnName + ' ASC,', '') + PKColumnName FROM #PKDetails ORDER BY ORDINAL_POSITION ASC 

/* Let's grab the foreign keys and put them into a temp table */ 
INSERT INTO #FKAgainstTableList (FKTable, FKName, FKColumnName) 
SELECT DISTINCT 
    KC.TABLE_NAME 
    ,KC.CONSTRAINT_NAME 
    ,STUFF((SELECT ',' + KCU.COLUMN_NAME 
      FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU 
      JOIN sys.foreign_keys FK ON KCU.CONSTRAINT_NAME = FK.name 
      WHERE OBJECT_NAME(fk.referenced_object_id) = @PKTableName AND KCU.CONSTRAINT_NAME = KC.CONSTRAINT_NAME 
      ORDER BY ORDINAL_POSITION ASC 
      FOR XML PATH('') 
      ),1,1,'') 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KC 
WHERE STUFF((SELECT ',' + KCU.COLUMN_NAME 
      FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU 
      JOIN sys.foreign_keys FK ON KCU.CONSTRAINT_NAME = FK.name 
      WHERE OBJECT_NAME(fk.referenced_object_id) = @PKTableName AND KCU.CONSTRAINT_NAME = KC.CONSTRAINT_NAME 
      ORDER BY ORDINAL_POSITION ASC 
      FOR XML PATH('') 
      ),1,1,'') IS NOT NULL 

/* Disable constraint on FK Tables */ 
DECLARE cursor1 CURSOR FOR 
    SELECT * FROM #FKAgainstTableList 

    PRINT @sql 

OPEN cursor1 
FETCH NEXT FROM cursor1 INTO @FKtable,@FKName,@FKColumnName 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @sql ='ALTER TABLE '[email protected]+' DROP CONSTRAINT '+ @FKName 
     PRINT @sql 
     --EXEC(@sql) 
     FETCH NEXT FROM cursor1 INTO @FKtable,@FKName,@FKColumnName 
    END 
CLOSE cursor1 
DEALLOCATE cursor1 


/* Let's drop that PK */ 
IF EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(@PKTableName) AND name = @PKName) 
BEGIN 
    SET @sql = 'ALTER TABLE '[email protected]+' DROP CONSTRAINT '+ @PKName 
    PRINT @sql 
    --EXEC(@sql) 

END 

/* Put your script here to drop and create the IDENTITY field */ 


/* OK, let's apply that PK (clustered) */ 
SET @sql = 'ALTER TABLE '[email protected] +' ADD CONSTRAINT '[email protected]+' PRIMARY KEY CLUSTERED ('[email protected]+' ASC) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]' 
PRINT(@sql) 
--EXEC(@sql) 

/* Put the FK's back on */ 
DECLARE cursor2 CURSOR FOR 
    SELECT * FROM #FKAgainstTableList 
OPEN cursor2 
FETCH NEXT FROM cursor2 INTO @FKtable,@FKName,@FKColumnName 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @sql = 'ALTER TABLE '[email protected]+' WITH CHECK ADD CONSTRAINT '+ @FKName+' FOREIGN KEY(['+REPLACE(@FKColumnName,',','],[')+']) 
     REFERENCES ['[email protected]+'] (['+REPLACE(@PKcolumnName,' ASC,','],[')+'])' 
     PRINT(@sql) 
     --EXEC(@sql) 

     FETCH NEXT FROM cursor2 INTO @FKtable,@FKName,@FKColumnName 
    END 
CLOSE cursor2 
DEALLOCATE cursor2 


/* Tidy up */ 
DROP TABLE #FKAgainstTableList 
DROP TABLE #PKDetails 

私はクラスタ化された1、元のコードに非クラスタ化PKを変換するためにしなければならなかったいくつかの仕事のために、このスクリプトは私のニーズに合わせてさまざまなソースから取得され、変更されている撮影しましたので、ご注意ください。私はこのコードのすべてを信用できません。

あなたはそれがSSMSのメッセージ]タブでやって何が起こっているか見ることができるように私はまた、コードの実行をコメントアウトしました。

+0

[OK]を、おかげで、私は、私は、すべての外部キー制約を削除してしまうと、どのように私は、私は同じように、その後、それらを再作成することを確認することができますか? – Platus

+0

#FKAgainstTableListを見て、必要な情報をスクリプトの冒頭の一時表に置きます。その後、このテーブルを使用して、FKを再作成するときの詳細を取得します。これを実行すると、SSMSの[メッセージ]タブで実行するコマンドが表示されます。私はexec関数をコメントアウトしたので、実行されません。 –

0

ID列を動作させるために必要な作業を行う前に、参照先の外部キーを先にドロップする必要があります。

関連する問題