我需要删除某些表中的所有数据。 DELETE FROM TableTwo
,DELETE FROM TableOne
等工作(它没有重新播种,但我可以学会接受它)。
我想通过截断表来做到这一点(因为它更快,我确信当我完成清空这些表时数据完整性会很好),但TableOne是一个依赖项TableTwo,所以一个天真的方法会给我错误“不能截断... FOREIGN KEY约束”。
我查看了约束文件夹并尝试了这个:
ALTER TABLE [TableOne] DROP CONSTRAINT [DF__Blahblah__38EE7070]
GO
TRUNCATE TABLE [TableOne]
GO
ALTER TABLE [TableOne] ADD DEFAULT ((0)) FOR [Something]
GO
然而它也会出现同样的错误。另外38EE7070对我来说是未知的,除非我手动检查所以无论如何我都会遇到问题。
我想知道我是否会忘记其他未知的约束,但是,当我试图检查EXEC sp_fkeys 'TableOne'
它显示空结果时,令人困惑的是。
鉴于sql server和azure的局限性,其他问题中的许多解决方案似乎都不可行。有谁知道我怎么办?即我如何删除并重新创建这些键?
答案 0 :(得分:2)
森,
我应该指出一些事情......
1)您发布的示例代码正在删除并创建DEFAULT CONSTRAINT(即,如果在插入期间未指定值,则设置列的默认值)。默认约束对截断表的能力没有影响(正如您正确指出的那样,不能截断具有外键约束的表)。
2)我认为sp_fkeys适用于SQL 2000,因此在SQL Server的更高版本中可能不再起作用(即使它仍然存在)。
下面我附上了一个脚本,用于识别表上的所有外键约束,并生成Create,Drop和Check语句。虽然我还没有在SQL Azure上使用它,但我已经在SQL Server 2008 R2的生产环境中多次使用它。
我希望它有所帮助。如果您有任何问题,请告诉我。
灰
CREATE FUNCTION [utils].[uf_ForeignKeyScripts]
(
@PrimaryKeyTable varchar(128), @PrimaryKeyTableSchema varchar(32)
)
RETURNS @Scripts TABLE
(
ForeignKeyName varchar(128)
, IfExistsStatement varchar(1000)
, DropStatement varchar(1000)
, IfNotExistsStatement varchar(1000)
, CreateStatement varchar(1000)
, CheckStatement varchar(1000)
, NoCheckStatement varchar(1000)
)
AS
/*
This function returns statements used to create, drop, and check all Foreign Key constraints that reference a given table.
These statements can be then added to T-SQL scripts.
Example usage (ensure selection of the Results to Text option in SSMS) :
1) To create statements to check all foreign keys
SELECT
IfExistsStatement + CHAR(13) +
CHAR(9) + CheckStatement + CHAR(13)
FROM
utils.uf_ForeignKeyScripts('t_Dim_Date','dbo')
;
This will return a formatted statement to check the existence of a foreign key and if it exists, check that data does not violate the key.
*/
BEGIN
INSERT INTO
@Scripts
(
ForeignKeyName
, IfExistsStatement
, DropStatement
, IfNotExistsStatement
, CreateStatement
, CheckStatement
, NoCheckStatement
)
SELECT
FK.name AS ForeignKeyName
, 'IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' + SFK.name + '.' + FK.name + ''') ' +
'AND parent_object_id = OBJECT_ID(N''' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + '''))'
AS IfExistsStatement
, 'ALTER TABLE ' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + ' ' +
'DROP CONSTRAINT ' + FK.name + CHAR(13) + ';'
AS DropStatement
, 'IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' + SFK.name + '.' + FK.name + ''') ' +
'AND parent_object_id = OBJECT_ID(N''' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + '''))'
AS IfNotExistsStatement
, 'ALTER TABLE ' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + ' ' +
'WITH CHECK ADD CONSTRAINT ' + FK.name + ' ' +
'FOREIGN KEY (' + C.FKColumns + ') ' +
'REFERENCES ' + ST.name + '.' + OBJECT_NAME(fk.referenced_object_id) + ' ' +
'(' + C.FKColumns + ')' + CHAR(13) + ';'
AS CreateStatement
, 'ALTER TABLE ' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + ' ' +
'CHECK CONSTRAINT ' + FK.name + CHAR(13) + ';'
AS CheckStatement
, 'ALTER TABLE ' + SFK.name + '.' + OBJECT_NAME(FK.parent_object_id) + ' ' +
'NOCHECK CONSTRAINT ' + FK.name + CHAR(13) + ';'
AS NoCheckStatement
FROM
sys.foreign_keys AS FK
INNER JOIN
sys.schemas AS SFK -- schema of foreign key table
ON
FK.schema_id = SFK.schema_id
INNER JOIN
sys.tables AS T -- primary key table
ON
FK.referenced_object_id = T.object_id
INNER JOIN
sys.schemas AS ST -- schema of primary key table
ON
T.schema_id = ST.schema_id
CROSS APPLY
(
/* Get all columns to handle composite keys */
SELECT
SFKC.constraint_object_id
, utils.uf_ConcatanateStringWithDelimiter(COL_NAME(SFKC.referenced_object_id, SFKC.referenced_column_id),', ') AS FKColumns
FROM
sys.foreign_key_columns AS SFKC
WHERE
SFKC.constraint_object_id = FK.object_id
GROUP BY
SFKC.constraint_object_id
)
AS C
WHERE
OBJECT_NAME(T.object_id) = @PrimaryKeyTable
AND ST.name = @PrimaryKeyTableSchema
;
RETURN
END
答案 1 :(得分:0)
唯一的方法是删除外键,截断表,然后重新创建外键。对于内部解决方案,您可能会采用此方法来计算事务日志的大小和性能。但是,在SQL Azure中,您并不关心事务日志。
答案 2 :(得分:0)
这不是我的原创作品(我想赞扬作者,但不记得我从哪里抓过它)但我发布它是因为它在SQL 2012中为我找到了表格的FK约束作为Azure SQL数据库:
选择 OBJECT_NAME(f.parent_object_id)TableName, COL_NAME(fc.parent_object_id,fc.parent_column_id)ColName 从 sys.foreign_keys AS f 内部联接 sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id 内部联接 sys.tables t ON t.OBJECT_ID = fc.referenced_object_id 哪里 OBJECT_NAME(f.referenced_object_id)='YourTableNameHere'按表名列出的顺序