Ich habe etwa 100 Tabellen, wo alle doppelte Fremdschlüssel Einschränkungen für sie haben.löschen doppelte Fremdschlüssel
Gibt es einen Weg, wie ich es loswerden könnte? Gibt es eine Abfrage, die mir alle doppelten Schlüssel geben könnte?
Ich habe etwa 100 Tabellen, wo alle doppelte Fremdschlüssel Einschränkungen für sie haben.löschen doppelte Fremdschlüssel
Gibt es einen Weg, wie ich es loswerden könnte? Gibt es eine Abfrage, die mir alle doppelten Schlüssel geben könnte?
Ich verwende dieses T-SQL-Skript hier, um potenziell doppelte FK-Einschränkungen zu erkennen - und es erzeugt auch die notwendigen ALTER TABLE...DROP CONSTRAINT
-Anweisungen in der letzten der Ausgabespalten.
Sie können nicht zuverlässig automatisch erkennen und auswählen, welche von mehreren FK-Abhängigkeiten fallen gelassen werden. Sie müssen sie also im Grunde erkennen und dann manuell auswählen, welche fallen gelassen werden sollen (mithilfe der von meiner Abfrage erstellten drop-Anweisung).
;WITH FKData AS
(
SELECT
fk.parent_object_id,
fkc.parent_column_id,
fk.referenced_object_id,
fkc.referenced_column_id,
FKCount = COUNT(*)
FROM
sys.foreign_keys fk
INNER JOIN
sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
GROUP BY
fk.parent_object_id, fkc.parent_column_id, fk.referenced_object_id, fkc.referenced_column_id
HAVING
COUNT(*) > 1
),
DuplicateFK AS
(
SELECT
FKName = fk.Name,
ParentSchema = s1.Name,
ParentTable = t1.Name,
ParentColumn = c1.Name,
ReferencedTable = t2.Name,
ReferencedColumn = c2.Name
FROM
sys.foreign_keys fk
INNER JOIN
sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
INNER JOIN
FKData f ON fk.parent_object_id = f.parent_object_id
AND fk.referenced_object_id = f.referenced_object_id
AND fkc.parent_column_id = f.parent_column_id
AND fkc.referenced_column_id = f.referenced_column_id
INNER JOIN
sys.tables t1 ON f.parent_object_id = t1.object_id
INNER JOIN
sys.columns c1 ON f.parent_object_id = c1.object_id AND f.parent_column_id = c1.column_id
INNER JOIN
sys.schemas s1 ON t1.schema_id = s1.schema_id
INNER JOIN
sys.tables t2 ON f.referenced_object_id = t2.object_id
INNER JOIN
sys.columns c2 ON f.referenced_object_id = c2.object_id AND f.referenced_column_id = c2.column_id
)
SELECT
FKName,
ParentSchema, ParentTable, ParentColumn,
ReferencedTable, ReferencedColumn,
DropStmt = 'ALTER TABLE ' + ParentSchema + '.' + ParentTable +
' DROP CONSTRAINT ' + FKName
FROM
DuplicateFK
für eine 100-Tabellen ist es keine Option, aber wenn man nur ein paar Tische haben, ein Diagramm, in dem SQL Server Management Studio erstellen, Ihre Tabellen dort hinzufügen und die Betrogenen visuell löschen.
Dies entfernt die zuletzt erstellten Duplikate
;WITH fkeys AS (
SELECT f.object_id ,
f.name ,
f.parent_object_id,
ROW_NUMBER() OVER(PARTITION BY t.column_names ORDER BY f.create_date,f.[object_id]) AS RowNum
FROM sys.foreign_keys f
CROSS APPLY (SELECT fc.parent_object_id,parent_column_id,fc.referenced_object_id ,fc.referenced_column_id
FROM sys.foreign_key_columns fc
WHERE fc.constraint_object_id = f.object_id
ORDER BY constraint_column_id
FOR XML PATH('')
) t (column_names)
)
SELECT 'ALTER TABLE '+QUOTENAME(OBJECT_SCHEMA_NAME(f.parent_object_id)) + '.'+QUOTENAME(OBJECT_NAME(f.parent_object_id)) +' DROP CONSTRAINT '+QUOTENAME(f.name)+';' AS DropStatement
FROM fkeys f
WHERE f.RowNum >= 2
Excellent Danke !! – peter
gibt es eine Möglichkeit, wie wir den Schemanamen auch bekommen könnten? da es einige gibt, die nicht zum dbo schema gehören. – peter
@Peter: ** SURE! ** aktualisierte meine Antwort, um das Elternschema einzuschließen (Sie könnten auch das referenzierte Schema erhalten, wenn nötig - aber Sie brauchen das nicht für die DROP-Anweisung) –