0

Hello I'm trying to disable all foreign key constraints on a database as I'm loading in some data. As it's part of a monthly job I want to do it dynamically so it can handle any changes. I'm trying to do this without using a cursor or temp table. I have built the statement below but so far this only creates an alter statement whereas I want it to execute the alter statement

declare @SQLStatement as nvarchar(4000)
SET @SQLStatement = 'exec (''select ''''alter table prpcref_mjp''''        + ''''.'''' + b.name + ''''.'''' + parent_tbl.name +  '''' NOCHECK CONSTRAINT '''' +  fk.name
from prpcref_mjp.sys.foreign_keys fk
inner join prpcref_mjp.sys.all_objects parent_tbl
    on fk.parent_object_id = parent_tbl.object_id
inner join prpcref_mjp.sys.schemas b
    on fk.schema_id = b.schema_id'')'
EXECUTE sp_executesql @SQLStatement
1
  • Are you concerned about how to recreate the foreign key constraints after all of the data has been loaded? Commented May 18, 2016 at 5:56

3 Answers 3

1

Leave the exec out of the string:

 select exec('alter table prpcref_mjp''' + 
'';'.'''' + 
        b.name + ''''.'''' + parent_tbl.name +  
            '''' NOCHECK CONSTRAINT '''' +  fk.name
                from prpcref_mjp.sys.foreign_keys fk
                inner join prpcref_mjp.sys.all_objects parent_tbl
                    on fk.parent_object_id = parent_tbl.object_id
                inner join prpcref_mjp.sys.schemas b
                    on fk.schema_id = b.schema_id')
Sign up to request clarification or add additional context in comments.

6 Comments

That just runs the select statement
@MattP answer updated, there might be some mistakes in the SQL (as i don't have SQL right now) but hopefully you got the idea.
this is as far as I could get. I can't seem to add a bracket onto the end of the 'exec' statement: declare @SQLStatement as nvarchar(4000) SET @SQLStatement = 'select ''exec(''''alter table prpcref_mjp'' + ''.'' + b.name + ''.'' + parent_tbl.name + '' NOCHECK CONSTRAINT ''+ fk.name from prpcref_mjp.sys.foreign_keys fk inner join prpcref_mjp.sys.all_objects parent_tbl on fk.parent_object_id = parent_tbl.object_id inner join prpcref_mjp.sys.schemas b on fk.schema_id = b.schema_id + '')''' exec(@SQLStatement)
you need to think about it in a different way, what am trying to do is a normal select statement with exec, the result will call exec for every result row.
thanks, makes sense. I've included 'exec' in the select however this only returns a result set and doesn't execute the alter command SET @SQLStatement = 'select ''exec(''''alter table prpcref_mjp'' + ''.'' + b.name + ''.'' + parent_tbl.name + '' NOCHECK CONSTRAINT ''+ fk.name + '''''')'' from prpcref_mjp.sys.foreign_keys fk inner join prpcref_mjp.sys.all_objects parent_tbl on fk.parent_object_id = parent_tbl.object_id inner join prpcref_mjp.sys.schemas b on fk.schema_id = b.schema_id' exec(@SQLStatement)
|
0
    select @NSQL = 'set @SQLStatement_out = ''''
select @SQLStatement_out += ''ALTER TABLE ' + @dbname + '.'' + b.name + ''.'' + parent_tbl.name + '' NOCHECK CONSTRAINT '' + fk.name + '';'' + char(13) + char(10)
  from ' + @dbname + '.' + 'sys.foreign_keys fk
 inner join ' + @dbname + '.' +'sys.all_objects parent_tbl
    on fk.parent_object_id = parent_tbl.object_id
 inner join ' + @dbname + '.' + 'sys.schemas b
    on fk.schema_id = b.schema_id
    exec(@SQLStatement_out) '

SET @ParmDefinition = N'@SQLStatement_out varchar(max) OUTPUT';

exec sp_executesql @NSQL, @ParmDefinition, @SQLStatement_out=@SQLStatement OUTPUT;

exec(@SQLStatement)

Comments

0

Here's another way to approach creating the string that contains all of the DDL statements:

declare @SQLStatement nvarchar(4000) = ''
select @SQLStatement += 'ALTER TABLE prpcref_mjp.' + b.name + '.' + parent_tbl.name + ' DROP CONSTRAINT ' + fk.name + ';' + char(13) + char(10)
  from prpcref_mjp.sys.foreign_keys fk
 inner join prpcref_mjp.sys.all_objects parent_tbl
    on fk.parent_object_id = parent_tbl.object_id
 inner join prpcref_mjp.sys.schemas b
    on fk.schema_id = b.schema_id
print @SQLStatement
exec(@SQLStatement)

You can add a where clause to limit the tables that you're going to modify. Comment out the exec() at the end if you want to see the code before actually running it.

Note that I added + char(13) + char(10) to make the output of the print statement easier to read.

1 Comment

Hey thanks @user212514 that worked a charm. Only issue was that I need to use fully qualified object names in the selects as I'm running it across multiple databases ie. prpcref_mjp.sys.all_objects. I'll provide an answer that reflects this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.