我正在使用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
唯一的问题是如果你有外键约束就没用了,因为你必须实际删除它们。有没有办法将此查询与将删除/重新创建所有约束的内容结合起来???
答案 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 constraints和Non-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');