SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vssCompareWorkToVss]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].[vssCompareWorkToVss] GO create procedure dbo.vssCompareWorkToVss @pDatabaseName varchar(30) as /*************************************************************************** Compare the contents of all folders in a local working folder hierarchy to the corrresponding project hierarchy in Visual SourceSafe. First compare objects, then compare contents This procedure does not script the database. Will not work with UNC paths. ****************************************************************************/ declare @Cmd nvarchar(1200), @returnStatus int, @procedureName varchar(255), @WorkingFolder varchar(255), @vssHierarchy varchar(255), @vssShare varchar(255), @vssUserName varchar(30), @line varchar(255), @diffCount int set nocount on set @diffCount = 0 set @procedureName = db_name() + '.' + user_name(objectproperty(@@procid,'OwnerId')) + '.' + object_name(@@procid) -- get file system path select @workingFolder = s.workingFolderRoot + p.projectName + '\' + e.environmentName + '\' + s.serverName + '\' + s.instanceName + '\' + @pDatabaseName, @vssShare = p.vssShare, @vssHierarchy = p.vssHierarchyRoot + e.environmentName + '/' + s.serverName + '/' + s.instanceName + '/' + @pDatabaseName + '/', @vssUserName = n.vssUserName from Admin.dbo.SqlDatabase d inner join Admin.dbo.ProjectNode n on d.id = n.sqlDatabase_id inner join Admin.dbo.SQlServer s on s.id = n.sqlServer_id inner join Admin.dbo.Environment e on e.id = n.environment_id inner join Admin.dbo.Project p on p.id = n.project_id where d.databaseName = @pDatabaseName --and s.id = Admin.dbo.thisSQLServer_id() cannot use function in SQL Server 7 and s.serverName = reverse(substring(reverse(@@servername), charindex('\',reverse(@@servername)) + 1, datalength(reverse(@@servername)))) and s.instanceName = substring(@@servername, charindex('\',@@servername) + 1, datalength(@@servername)) and n.IsActive = 1 -- valid project node must exist if @@rowcount = 0 begin raiserror(59002,16,1,@procedureName,@pDatabaseName) return -1 end -- wrong user asking if substring(system_user,charindex('\', system_user) + 1, datalength(system_user)) <> @vssUserName begin set @vssUserName = substring(system_user,charindex('\', system_user) + 1, datalength(system_user)) raiserror (59005,16,1, @procedurename, @vssUserName, @vssShare) goto ErrorHandler end -- file system working folder for the database must exist set @cmd = 'dir ' + @WorkingFolder exec @returnstatus = master.dbo.xp_cmdshell @CMD, no_output if @returnstatus <> 0 begin raiserror (59007,16,1,@procedureName, @WorkingFolder,@@servername) return -1 end -- vss project must exist - must be created by vss admin -- NOTE! if you put a password on vss, this will hang (tries to prompt for password) -- if the database folder already exists, this procedure cannot be used set @cmd = @vssShare + 'win32\ss Cp ' + @vssHierarchy + ' -I-N -Y' + @vssUserName exec @returnstatus = master.dbo.xp_cmdshell @cmd, no_output if @returnstatus <> 0 begin raiserror(59008,16,1,@procedureName, @vssHierarchy, @vssShare) goto ErrorHandler end -- compare objects set @Cmd = substring(@WorkingFolder,1,2) + '&cd ' + substring(@WorkingFolder,3,datalength(@WorkingFolder)) + '&' + @vssShare + 'win32\ss Diff ' --+ @vssHierarchy + ' -R -B -Y' + @vssUserName exec @returnstatus = master.dbo.xp_cmdshell @Cmd, NO_OUTPUT if @returnstatus = 1 begin print '' print 'Object Differences were found! ' print '' create table #ObjectDifferences(output varchar(255)) insert #ObjectDifferences exec master.dbo.xp_cmdshell @Cmd update #ObjectDifferences set output = '' where output is NULL select * from #ObjectDifferences drop table #ObjectDifferences end else begin if @returnstatus <> 0 goto ErrorHandler else begin print '' print 'No Object Differences found.' end end -- compare contents -- get list of all files in the working folder create table #fileList (line varchar(255)) set @Cmd = 'dir ' + @WorkingFolder + ' /A /S /B' insert #fileList exec master.dbo.xp_cmdshell @Cmd -- a little clean up of the list -- only .sql files delete #fileList where line not like '%.sql' or line is null -- position just past the database name update #fileList set line = substring(line, datalength(@workingFolder) + 2, datalength(line)) -- compare each file to it's VSS mate set @line = (select top 1 line from #fileList order by line) while @line is not null begin set @Cmd = @vssShare + 'win32\ss Diff ' --+ @vssHierarchy + replace(@line,'\','/') + ' ' + @workingFolder + '\' + @line + ' -DS -Y' + @vssUSerName exec @returnstatus = master.dbo.xp_cmdshell @Cmd, NO_OUTPUT if @returnstatus = 1 begin set @diffCount = @diffCount + 1 print '' print 'Content Differences were found!' print '' create table #ContentDifferences(output varchar(255)) insert #ContentDifferences exec master.dbo.xp_cmdshell @Cmd update #ContentDifferences set output = '' where output is NULL select * from #ContentDifferences drop table #ContentDifferences end else if @returnstatus <> 0 goto ErrorHandler delete #fileList where line = @line set @line = (select top 1 line from #fileList order by line) end if @diffCOunt = 0 begin print '' print 'No Content Differences found.' end print '' print 'Compare complete' return ErrorHandler: insert Admin.dbo.ActivityLog (activity) select @procedureName + ' ' + @pDatabaseName + ' failed with returnstatus ' + cast(@returnstatus as varchar(10)) + ' at: ' + @cmd raiserror(59001,16,1,@procedureName) return -1 GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO