Technical Article

Script foreign keys

,

Return list of commands which can be used for different purposes like recreating foreign keys, disabling or enabling foreign keys. All data about foreign keys are collected so you can modify this script in an easy way.

If you are going to use query output as an input command than be sure that maximum number of characters displayed in column in query window is big enough and your command is not truncated. Spell check is strongly recommended before execution!

DECLARE
 @constraint_name sysname,
 @parent_schema sysname,
 @parent_name sysname,
 @referenced_object_schema sysname,
 @referenced_object_name sysname,
 @column_name sysname,
 @referenced_column_name sysname,
 @is_not_for_replication bit,
 @is_not_trusted bit,
 @delete_referential_action tinyint,
 @update_referential_action tinyint,
 @AddLine nvarchar(max),
 @DropLine nvarchar(max),
 @fkline nvarchar(max),
 @pkline nvarchar(max),
 @object_id int,
 @parent_object_id int

DECLARE 
 @AddScript TABLE (line nvarchar(max))
DECLARE 
 @DropScript TABLE (line nvarchar(max))

 SET NOCOUNT ON

 -- Create cursor for foreign keys system view
 DECLARE cFKeys CURSOR READ_ONLY
 FOR 
 SELECT object_id, 
 parent_object_id, 
 OBJECT_SCHEMA_NAME(parent_object_id), 
 object_name (parent_object_id), 
 [name], 
 is_not_trusted, 
 OBJECT_SCHEMA_NAME(referenced_object_id), 
 object_name(referenced_object_id),
 delete_referential_action,
 update_referential_action,
 is_not_for_replication
 FROM sys.foreign_keys
 
 OPEN cFKeys
 
 -- Collect basic data
 FETCH NEXT FROM cFKeys INTO @object_id, @parent_object_id, @parent_schema, @parent_name, @constraint_name, @is_not_trusted, @referenced_object_schema, @referenced_object_name, @delete_referential_action, @update_referential_action, @is_not_for_replication
 WHILE (@@fetch_status <> -1)
 BEGIN
 IF (@@fetch_status <> -2)
 BEGIN
 -- Start creating command string. One for add and one for drop constraint
 SET @AddLine = N'ALTER TABLE ' + quotename(@parent_schema) + N'.' + quotename(@parent_name)
 SET @DropLine = N'ALTER TABLE ' + quotename(@parent_schema) + N'.' + quotename(@parent_name)
 -- Check if it is enabled or not
 IF @is_not_trusted = 1
 SET @AddLine = @AddLine + N' WITH NOCHECK'
 ELSE
 SET @AddLine = @AddLine + N' WITH CHECK'
 
 SET @AddLine = @AddLine + N' ADD CONSTRAINT ' + quotename(@constraint_name) + N' FOREIGN KEY (' 
 SET @DropLine = @DropLine + N' DROP CONSTRAINT ' + quotename(@constraint_name)
 
 -- Gather all columns for current key from foreign key columns system view
 DECLARE cColumns CURSOR READ_ONLY
 FOR 
 SELECT fc.name, pc.name
 FROM sys.foreign_key_columns fk 
 inner join sys.columns fc on fk.parent_object_id = fc.object_id and fk.parent_column_id = fc.column_id
 inner join sys.columns pc on fk.referenced_object_id = pc.object_id and fk.referenced_column_id = pc.column_id
 WHERE parent_object_id = @parent_object_id and fk.constraint_object_id = @object_id
 
 OPEN cColumns
 
 SET @fkline = N''
 SET @pkline = N''
 
 FETCH NEXT FROM cColumns INTO @column_name, @referenced_column_name
 WHILE (@@fetch_status <> -1)
 BEGIN
 IF (@@fetch_status <> -2)
 BEGIN
 -- One line for column list and one for referenced columns
 SET @fkline = @fkline + @column_name
 SET @pkline = @pkline + @referenced_column_name
 END
 FETCH NEXT FROM cColumns INTO @column_name, @referenced_column_name
 IF (@@fetch_status = 0)
 BEGIN
 SET @fkline = @fkline + ', '
 SET @pkline = @pkline + ', '
 END
 END
 
 CLOSE cColumns
 DEALLOCATE cColumns
 -- Add column list
 SET @AddLine = @AddLine + @fkline + N')' + CHAR(13) 
 -- Add referenced table and column list
 SET @AddLine = @AddLine + 'REFERENCES ' + quotename(@referenced_object_schema) + N'.' + quotename(@referenced_object_name) 
 SET @AddLine = @AddLine + N' (' + @pkline + N')'
 -- Check the referential action that was declared for this key as well as replication option
 SET @AddLine = @AddLine +
 ' ON DELETE' + 
 CASE @delete_referential_action 
 WHEN 1 THEN N' CASCADE'
 WHEN 2 THEN N' SET NULL'
 WHEN 3 THEN N' SET DEFAULT'
 ELSE N' NO ACTION'
 END +
 ' ON UPDATE' +
 CASE @UPDATE_REFERENTIAL_ACTION
 WHEN 1 THEN N' CASCADE'
 WHEN 2 THEN N' SET NULL'
 WHEN 3 THEN N' SET DEFAULT'
 ELSE N' NO ACTION'
 END +
 CASE 
 WHEN @IS_NOT_FOR_REPLICATION = 1 THEN N' NOT FOR REPLICATION'
 ELSE N''
 END
 -- Insert command into table for later use
 INSERT INTO @DropScript SELECT @DropLine
 INSERT INTO @AddScript SELECT @AddLine
 
 FETCH NEXT FROM cFKeys INTO @object_id, @parent_object_id, @parent_schema, @parent_name, @constraint_name, @is_not_trusted, @referenced_object_schema, @referenced_object_name, @delete_referential_action, @update_referential_action, @is_not_for_replication
 END
 END
 
 CLOSE cFKeys
 DEALLOCATE cFKeys
 
 SET NOCOUNT OFF
 
 SELECT line FROM @DropScript
 SELECT line FROM @AddScript

Rate

4.29 (17)

You rated this post out of 5. Change rating

Share

Share

Rate

4.29 (17)

You rated this post out of 5. Change rating