Too often I face a terrible situation: I have a little time to take the backup of a customer db and download it for studying problems on it.
The problem is that the database contains many BLOBs (as sql server filestream
).
Typically tabular data ("mdf") is 5% of the total data.
To study most issues I do not need BLOBs.
In a world with infinite bandwidth I could simply take a backup and download it, but this conflicts with "a little time" in the real world.
To get rid of BLOBs I also do:
- create a copy of the DB at the customer server
- set all blobs to
NULL
- run CHECKPOINT to force filestream data clearing from disk
- take backup after some time (proportional to BLOBs total size)
- download a small backup
BUT point (4) takes time.
So what I would like to achieve is:
a) create an empty database with a filestream filegroup on the customer's server
b) with a script, create the schema (at least tables, views, sp, sf) on the copied DB
c) with a script copy all the data but not the BLOBs
d) take backup and download
With my knowledge I can somehow manage (b) using the Tasks/Generate Scripts feature of Management Studio.
Then manually I should write queries like this to fill the tables:
INSERT INTO CopiedDB.dbo.Table1
SELECT * from MainDB.dbo.Table1
It is a very long procedure to be done manually even because the insert order must be sorted out manually (because of FK
relationships).
Is there a way to create this script in a smart way avoiding the manual way?
Best Answer
Disable all your foreign keys before you start the transfer and then reenable them afterwards.
You might also want to think about your indexes, it's usually much quicker to disable the indexes before copying data and then rebuild them afterwards.
https://sqlundercover.com/2017/09/25/copying-data-from-one-table-to-another-to-disable-indexes-or-not-to-disable-indexes-thats-the-question/
Have a look at the below scriopt this is part of a much larger script so you might want to check that it does what you want but it should be ok. Just assign the relevant database names to the @SourceDatabase and @DestinationDatabase variables.
It'll deal with your indexes and constraints, disabling them before and reenabling them after the transfer. As I said, I've pulled this out of the much bigger process and tweaked it slightly so make sure you test it out.