あなたがテーブルに基づいて、すべての外部キーを見つけるために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
のメッセージ]タブでやって何が起こっているか見ることができるように私はまた、コードの実行をコメントアウトしました。
ドロップ2つのFKS最初 – Sami