删除并重新创建所有约束与sp_MSForEachTable sql server结合使用

时间:2011-09-19 13:35:10

标签: sql-server

我正在使用SSIS将一些测试数据加载到我们的数据仓库中,并且遇到了外键约束的旧问题。我将在我的本地测试环境中删除/添加所有数据以查找数据问题。因此,我现在不太关心参照完整性......我遇到了这个方便的小问题:

-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NO CHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?' 
GO 

-- enable referential integrity again 
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 
GO

唯一的问题是如果你有外键约束就没用了,因为你必须实际删除它们。有没有办法将此查询与将删除/重新创建所有约束的内容结合起来???

3 个答案:

答案 0 :(得分:6)

   --Drop and Recreate Foreign Key Constraints

SET NOCOUNT ON

DECLARE @table TABLE(
   RowId INT PRIMARY KEY IDENTITY(1, 1),
   ForeignKeyConstraintName NVARCHAR(200),
   ForeignKeyConstraintTableSchema NVARCHAR(200),
   ForeignKeyConstraintTableName NVARCHAR(200),
   ForeignKeyConstraintColumnName NVARCHAR(200),
   PrimaryKeyConstraintName NVARCHAR(200),
   PrimaryKeyConstraintTableSchema NVARCHAR(200),
   PrimaryKeyConstraintTableName NVARCHAR(200),
   PrimaryKeyConstraintColumnName NVARCHAR(200)    
)

INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
SELECT 
   U.CONSTRAINT_NAME, 
   U.TABLE_SCHEMA, 
   U.TABLE_NAME, 
   U.COLUMN_NAME 
FROM 
   INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
         ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE
   C.CONSTRAINT_TYPE = 'FOREIGN KEY'

UPDATE @table SET
   PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME
FROM 
   @table T
      INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
         ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintTableSchema  = TABLE_SCHEMA,
   PrimaryKeyConstraintTableName  = TABLE_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
      ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintColumnName = COLUMN_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME

--SELECT * FROM @table

--DROP CONSTRAINT:
SELECT
   '
   ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
   DROP CONSTRAINT ' + ForeignKeyConstraintName + '

   GO'
FROM
   @table

--ADD CONSTRAINT:
SELECT
   '
   ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
   ADD CONSTRAINT ' + ForeignKeyConstraintName + ' FOREIGN KEY(' + ForeignKeyConstraintColumnName + ') REFERENCES [' + PrimaryKeyConstraintTableSchema + '].[' + PrimaryKeyConstraintTableName + '](' + PrimaryKeyConstraintColumnName + ')

   GO'
FROM
   @table

GO

答案 1 :(得分:3)

不幸的是没有

您必须使用外键删除表

-- disable referential integrity
EXEC sp_MSForEachTable 'ALTER TABLE ? NO CHECK CONSTRAINT ALL' 
GO 
EXEC sp_MSForEachTable 'DELETE ?' 
GO 
-- enable referential integrity again 
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 
GO

或者,首先编写脚本并删除约束,稍后再添加tjem。
为此,请参阅本文"Script out your foreign keys"

答案 2 :(得分:2)

如果您使用ALTER TABLE ? CHECK CONSTRAINT ALL启用约束,则会获得不受信任的约束。请阅读Tibor Karaszi SQL Server MVP撰写的这些文章:Non-trusted constraintsNon-trusted constraints and performance。 尝试使用ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL

示例:

CREATE TABLE Persoana
(
    IdPersoana INT IDENTITY(1,1) PRIMARY KEY
    ,Nume NVARCHAR(50) NOT NULL
    ,Prenume NVARCHAR(50) NOT NULL
    ,Varsta TINYINT NOT NULL
    ,CONSTRAINT CK_Persoana_Nume CHECK ( Nume <> '' )
    ,CONSTRAINT CK_Persoana_Prenume CHECK ( Prenume <> '' )
    ,CONSTRAINT CK_Persoana_Varsta CHECK( Varsta >= 18 )
);

INSERT dbo.Persoana 
VALUES ('A','AA',22);

SELECT  cc.name, cc.is_disabled, cc.is_not_trusted
FROM    sys.check_constraints cc
WHERE   cc.parent_object_id = OBJECT_ID('dbo.Persoana');

ALTER TABLE dbo.Persoana NOCHECK CONSTRAINT ALL;
ALTER TABLE dbo.Persoana CHECK CONSTRAINT ALL;

SELECT  cc.name, cc.is_disabled, cc.is_not_trusted
FROM    sys.check_constraints cc
WHERE   cc.parent_object_id = OBJECT_ID('dbo.Persoana');

ALTER TABLE dbo.Persoana WITH CHECK CHECK CONSTRAINT ALL;
SELECT  cc.name, cc.is_disabled, cc.is_not_trusted
FROM    sys.check_constraints cc
WHERE   cc.parent_object_id = OBJECT_ID('dbo.Persoana');