Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
368

Hi All,

Here is a TSQL query example to generate a test database from a production database. It can be planned through SQL Maintenance plan to have TestDB updated from Productive DB from a regular basis.

Update SQL Variables with desired values :

@PRODdatabaseName :  Source DB Name

@TESTdatabaseName : Target DB Name (will be deleted before restore if DB already exists)

@SQLDATAPath : Path for storing mdb and mdf files for the targetDB.

@BackupPath : Path for storing the backup file. (will be deleted and regenerated on each execution)

Add the query into SQL maintenance plan and plan recuring execution.

Code Snippet
-- =======================================================================================
-- Version :     <1.03>
-- Author:       <Emmanuel ALBERT, ealbert@self-informatique.fr>
-- Description:  <Create Backup from specified DB and restore as test DB>
-- Create date:  <18 Fev 2014,,>
-- Update Date : <19 Fev 2014, overwriting existing backup set,             
--                Switch TestDB to recovery mode=Simple and clean logs. >
-- Update Date : <13 Mars 2014, Closing opening connection if existings on testDB before Restore,,>
--
-- =======================================================================================

use [master]
go

declare @PRODdatabaseName nvarchar (128)
set @PRODdatabaseName= 'SBODemoFr';
declare @TESTdatabaseName nvarchar (128)
set @TESTdatabaseName= 'SBODemoFr_Test_UpToDate';

Declare @SQLDATAPath as nvarchar( 128);
  Set@SQLDATAPath = 'd:\temp\'

declare @BackupPath nvarchar (128);
   set @BackupPath ='d:\temp\' + @PRODdatabaseName + '.bak' ;

DECLARE @SQL_SCRIPT VARCHAR (MAX);
Declare @TSQL_DROP_Template VARCHAR (MAX)
Set @TSQL_DROP_Template= 'DROP DATABASE {DBNAME}';

--Testing if SourceDB exists before starting :
  IFEXISTS (SELECT name FROM sys.databases WHERE name = @PRODdatabaseName)
BEGIN
Print 'Staring Prod DB Backup - (WITH FORMAT, INIT, COMPRESSION)'
  BACKUP DATABASE  @PRODdatabaseName  --BAckup BDPROD
  TO DISK = @BAckupPath WITH INIT
    
Print 'Test TargetDB exists and drop if true'
  -- Test TargetDB exists and drop if true:
  IF  EXISTS ( SELECT name FROM sys. databases WHERE name = @TESTdatabaseName)
      Begin
      Print 'Target DB Exists : '
      --Kill Opened Connections :
      Print 'Trying to Kill Open Connection on TargetDB'
                         DECLARE @dbid tinyint
                         DECLARE @spid smallint
                         DECLARE @exec_str varchar (10)


                         -- Get the ID of the Database you wish to kill the connections of
                         SET @dbid = DB_ID( @TESTdatabaseName)

                         -- Set a var to the first process ID connecting to that database
                         SET @spid = (SELECT MIN( spid) FROM master..sysprocesses WHERE dbid = @dbid)

                         WHILE @spid IS NOT NULL
                         BEGIN
                         IF @spid <> @@SPID -- Make sure you don't drop your own connection
                         BEGIN
                         SET @exec_str = 'KILL '+ LTRIM(STR (@spid))
                         Print 'Killing Connection ' + LTRIM(STR (@spid))
                         EXEC(@exec_str ) -- Kill the connection
                         END
                         --Get next SPID
                         SET @spid = (SELECT MIN( spid) FROM master..sysprocesses WHERE dbid = @dbid AND spid > @spid)
                         END
                   SET @SQL_SCRIPT = REPLACE( @TSQL_DROP_Template, '{DBNAME}', @TESTdatabaseName )
            EXECUTE (@SQL_SCRIPT ) --Suppression Base Test si existante
            Print 'Old TargetDB deleted'
      End
    
  Declare @TSQL_REstore_FileList_Template VArchar(MAX )
  SET @TSQL_REstore_FileList_Template ='RESTORE FILELISTONLY FROM DISK=''{BackupPath}'' '
  Declare @TSQL_Restore_Template VARCHAR(MAX )
  Set @TSQL_Restore_Template ='RESTORE DATABASE {DBNAME} FROM DISK=''{BackupPath}'' WITH REPLACE,RECOVERY, MOVE ''{DataVolNAme}'' TO ''{TargetDataVolNAme}'', MOVE ''{LogName}'' TO ''{TargetLogNAme}''';

--Manage mdf and ldf filenames..
Print 'Manage mdf and ldf filenames'
DECLARE @FileList TABLE
      (
      LogicalName nvarchar(128 ) NOT NULL,
      PhysicalName nvarchar(260 ) NOT NULL,
      Type char (1) NOT NULL,
      FileGroupName nvarchar(120 ) NULL,
      Size numeric(20 , 0) NOT NULL,
      MaxSize numeric(20 , 0) NOT NULL,
      FileID bigint NULL,
      CreateLSN numeric(25 ,0) NULL,
      DropLSN numeric(25 ,0) NULL,
      UniqueID uniqueidentifier NULL,
      ReadOnlyLSN numeric(25 ,0) NULL ,
      ReadWriteLSN numeric(25 ,0) NULL,
      BackupSizeInBytes bigint NULL,
      SourceBlockSize int NULL,
      FileGroupID int NULL,
      LogGroupGUID uniqueidentifier NULL,
      DifferentialBaseLSN numeric(25 ,0)NULL,
      DifferentialBaseGUID uniqueidentifier NULL,
      IsReadOnly bit NULL,
      IsPresent bit NULL,
      TDEThumbprint varbinary(32 ) NULL
);

declare @RestoreStatement nvarchar (max), @BackupFile nvarchar( max);
set @BackupFile = @BackupPath

   SET @RestoreStatement =N'RESTORE FILELISTONLY
      FROM DISK=N''' + @BackupFile + ''''

INSERT INTO @FileList
      EXEC(@RestoreStatement );

declare @logical_data nvarchar (max), @logical_log nvarchar( max);
set @logical_data = (select LogicalName from @FileList where Type = 'D' and FileID = 1)
set @logical_log = (select LogicalName from @FileList where Type = 'L' and FileID = 2)

--Running restore with new filenames
Print 'Starting TargetDB restore'
       SET @SQL_SCRIPT = REPLACE( @TSQL_Restore_Template, '{DBNAME}', @TESTdatabaseName)
       SET @SQL_SCRIPT = REPLACE( @SQL_SCRIPT, '{BackupPath}', @BackupPath)
       SET @SQL_SCRIPT = REPLACE( @SQL_SCRIPT, '{DataVolNAme}', @logical_data)
       Declare @DynPath as nvarchar( 128);
       set  @DynPAth= @SQLDATAPath + @TESTdatabaseName + '.mdf'

       SET @SQL_SCRIPT = REPLACE( @SQL_SCRIPT, '{TargetDataVolNAme}', @DynPAth)
       SET @SQL_SCRIPT = REPLACE( @SQL_SCRIPT, '{LogName}', @logical_log )
       set  @DynPAth= @SQLDATAPath +  @TESTdatabaseName +'.ldf'
       SET @SQL_SCRIPT = REPLACE( @SQL_SCRIPT, '{TargetLogNAme}', @DynPAth)
       EXECUTE (@SQL_SCRIPT )
       Print 'TargetDB restored' ;
 
   --Switch to recovery mode=simple and clean ldf logs
         exec( 'alter database [' + @TESTdatabaseName + '] set recovery Simple')
         exec( '
            use [' + @TESTdatabaseName + '];' +'
      
            declare @logfileName nvarchar(128);
            set @logfileName = (
                  select top 1 [name] from sys.database_files where [type] = 1
            );
            dbcc shrinkfile(@logfileName,1);
            ' )

  END

Feel free to comment,

Regards;

Emmanuel

Labels in this area