Monday, April 30, 2012

I updated my previous entry as a stored procedure with error catching and rollback. usage: EXEC dbo.usp_CloneDBData @srcdb, @dstdb -- Source and Destination database names respectively. This version does not work using linked servers, but could easily be modified to do so.
 CREATE PROCEDURE dbo.usp_CloneDBData -- table schemas must be identical  
  @srcdb AS VARCHAR(1000),  
  @dstdb AS VARCHAR(1000)  
 AS  
 --DECLARE @srcdb AS VARCHAR(1000)  
 --DECLARE @dstdb AS VARCHAR(1000)  
 --SET @srcdb = '[_test1]'  
 --SET @dstdb = '_test2'  
 DECLARE @allsql AS NVARCHAR(4000)  
 SET @srcdb = '[' + REPLACE(REPLACE(@srcdb,'[',''),']','') + ']'  
 SET @dstdb = '[' + REPLACE(REPLACE(@dstdb,'[',''),']','') + ']'  
 IF (@srcdb = @dstdb)   
 BEGIN  
     RAISERROR ('Source and Destination Databases cannot be the same', 16, 1)  
     RETURN  
 END  
 SET @allsql = '  
 -- truncate and refill from an identical table in another database  
 EXEC '+@dstdb+'.dbo.sp_msforeachtable ''ALTER TABLE ? NOCHECK CONSTRAINT all''  
 DECLARE cur CURSOR FOR  
   SELECT table_name, table_schema  
   FROM '+@srcdb+'.INFORMATION_SCHEMA.tables tab   
   WHERE table_type = ''BASE TABLE''  
 OPEN cur  
 DECLARE @tablename VARCHAR(255) ,@tableschema VARCHAR(255)  
 FETCH NEXT FROM cur INTO @tablename, @tableschema  
 WHILE ( @@FETCH_STATUS <> -1 )   
 BEGIN   
   IF ( @@FETCH_STATUS <> -2 )   
   DECLARE @sqltxt NVARCHAR(4000)  
     DECLARE @columnlist VARCHAR(4000)  
     Select @columnlist = ISNULL(Stuff(  
             (  
             Select '', '' + C.COLUMN_NAME  
             From [_Test1].INFORMATION_SCHEMA.COLUMNS As C  
             Where C.TABLE_SCHEMA = T.TABLE_SCHEMA  
                 And C.TABLE_NAME = T.TABLE_NAME  
             Order By C.ORDINAL_POSITION  
             For Xml Path('''')  
             ), 1, 2, '''') ,'''')  
     From [_Test1].INFORMATION_SCHEMA.TABLES As T  
     WHERE T.TABLE_NAME = @tablename  
  SET @sqltxt = N''''  
 EXEC dbo.sp_executesql @sqltxt  
  SET @sqltxt = N''  
 use '+@dstdb+';  
 DELETE ['' + @tableschema + ''].['' + @tablename + ''];  
 IF ((SELECT OBJECTPROPERTY( OBJECT_ID(N''''['' + @tableschema + ''].['' + @tablename + '']''''), ''''TableHasIdentity'''')) = 1) SET IDENTITY_INSERT ['' + @tableschema + ''].['' + @tablename + ''] ON;  
 INSERT INTO ['' + @tableschema + ''].['' + @tablename + ''] (''+@columnlist+'') SELECT ''+@columnlist+'' FROM [_Test1].['' + @tableschema + ''].['' + @tablename + ''];  
 IF ((SELECT OBJECTPROPERTY( OBJECT_ID(N''''['' + @tableschema + ''].['' + @tablename + '']''''), ''''TableHasIdentity'''')) = 1) SET IDENTITY_INSERT ['' + @tableschema + ''].['' + @tablename + ''] OFF;  
 ''  
 EXEC dbo.sp_executesql @sqltxt  
 FETCH NEXT FROM cur INTO @tablename, @tableschema  
 END  
 CLOSE cur  
 DEALLOCATE cur  
 exec '+@dstdb+'.dbo.sp_msforeachtable ''ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all''  
 '  
 BEGIN TRY  
     BEGIN TRAN  
         EXEC dbo.sp_executesql @allsql  
     COMMIT TRAN  
 END TRY  
 BEGIN CATCH   
   DECLARE @ErrorMessage NVARCHAR(4000);  
   DECLARE @ErrorSeverity INT;  
   --DECLARE @ErrorState INT;  
   SELECT   
     @ErrorMessage = ERROR_MESSAGE(),  
     @ErrorSeverity = ERROR_SEVERITY()  
     --,@ErrorState = ERROR_STATE();  
   RAISERROR (@ErrorMessage, -- Message text.  
         @ErrorSeverity, -- Severity.  
         1 -- State.  
         );  
     ROLLBACK TRAN  
 END CATCH  

No comments: