这里提供一种免费比较数据库的方法。
下面是我编写的 SQL Server 脚本,它可以将数据库中存储过程、视图和表的内容输出到输出窗口。
通过调用以下命令来运行它:
exec [dbo].[ScriptStoredProcedures]
在我的许多项目中,我会运行此脚本,将文本复制到Visual Studio项目中的文件中,以便我可以检查我们的数据库在特定时间的外观副本。
(是的,您也可以在Visual Studio中拥有Database Projects,但这是一种替代方法。)
如果您在两个数据库上运行此脚本,则可以比较两个输出以查找差异。
CREATE PROCEDURE [dbo].[ScriptStoredProcedures]
AS
BEGIN
SET NOCOUNT ON
PRINT '--'
PRINT '-- SQL Script, generated by the [ScriptStoredProcedures] Stored Procedure.'
PRINT '-- Created on ' + convert(nvarchar, GetDate(), 106) + ' ' + convert(nvarchar, GetDate(), 108)
PRINT '--'
PRINT '-- This will create/update the Stored Procedures on this database, to bring them up-to-date with the SPs '
PRINT '-- from the database ''' + DB_NAME() + ''' on the server ''' + @@SERVERNAME + ''''
PRINT '--'
PRINT '--'
CREATE TABLE #tmp
(
[inx] INT IDENTITY(1, 1),
[text] nvarchar(4000)
)
DECLARE @StoredProcedureName NVARCHAR(200)
DECLARE @StoredProcedureType NVARCHAR(10)
DECLARE @ExecCommand NVARCHAR(200)
DECLARE @OneLineOfScript NVARCHAR(4000)
DECLARE cursorEachStoredProcedure CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT [name],
[type]
FROM sysobjects
WHERE (OBJECTPROPERTY(id, N'IsProcedure') = 1
OR OBJECTPROPERTY(id, N'IsTableFunction') = 1
OR OBJECTPROPERTY(id, N'IsScalarFunction') = 1
OR OBJECTPROPERTY(id, N'IsView') = 1)
AND [name] NOT LIKE 'sp_%'
AND [name] NOT LIKE 'fn_%'
ORDER BY [type] DESC,
[name]
OPEN cursorEachStoredProcedure
FETCH NEXT FROM cursorEachStoredProcedure INTO @StoredProcedureName, @StoredProcedureType
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT ''
IF (@StoredProcedureType = 'P')
BEGIN
PRINT 'PRINT ''Creating stored procedure: ''''' + @StoredProcedureName + ''''''''
PRINT ''
PRINT 'IF EXISTS(select Name from sysobjects where OBJECTPROPERTY(id, N''IsProcedure'') = 1 AND Name = ''' + @StoredProcedureName + ''')'
PRINT 'BEGIN'
PRINT ' DROP PROCEDURE [' + @StoredProcedureName + '] '
PRINT 'END'
END
ELSE
IF (@StoredProcedureType = 'V')
BEGIN
PRINT 'PRINT ''Creating view: ''''' + @StoredProcedureName + ''''''''
PRINT ''
PRINT 'IF EXISTS(select Name from sysobjects where OBJECTPROPERTY(id, N''IsView'') = 1 AND Name = ''' + @StoredProcedureName + ''')'
PRINT 'BEGIN'
PRINT ' DROP VIEW [' + @StoredProcedureName + '] '
PRINT 'END'
END
ELSE
BEGIN
PRINT 'PRINT ''Creating function: ''''' + @StoredProcedureName + ''''''''
PRINT ''
PRINT 'IF EXISTS(select Name from sysobjects where (OBJECTPROPERTY(id, N''IsTableFunction'') = 1 OR OBJECTPROPERTY(id, N''IsScalarFunction'') = 1) AND Name = ''' + @StoredProcedureName + ''')'
PRINT 'BEGIN'
PRINT ' DROP FUNCTION [' + @StoredProcedureName + '] '
PRINT 'END'
END
PRINT 'GO '
SET @ExecCommand = 'sp_helptext @objname = ''' + @StoredProcedureName + ''''
DELETE FROM #tmp
INSERT INTO #tmp
EXEC(@ExecCommand)
DECLARE cursorEachLineOfScript CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT [text]
FROM #tmp
ORDER BY [inx]
OPEN cursorEachLineOfScript
FETCH NEXT FROM cursorEachLineOfScript INTO @OneLineOfScript
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @OneLineOfScript
FETCH NEXT FROM cursorEachLineOfScript INTO @OneLineOfScript
END
CLOSE cursorEachLineOfScript
DEALLOCATE cursorEachLineOfScript
PRINT 'GO '
FETCH NEXT FROM cursorEachStoredProcedure INTO @StoredProcedureName, @StoredProcedureType
END
CLOSE cursorEachStoredProcedure
DEALLOCATE cursorEachStoredProcedure
DROP TABLE #tmp
PRINT 'EXEC [dbo].[spGrantExectoAllStoredProcs]'
PRINT 'GO'
PRINT '--'
PRINT '--'
PRINT '-- List of tables (and their fields) in this database'
PRINT '--'
PRINT '--'
PRINT '--'
DECLARE
@tableName nvarchar(200),
@fieldName nvarchar(500),
@fieldType nvarchar(500),
@fieldNullable nvarchar(200)
DECLARE cursorTables CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT st.NAME as 'Table_name'
FROM sys.tables st
ORDER BY 1
OPEN cursorTables
FETCH NEXT FROM cursorTables INTO @tableName
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT '-- Table: ' + @tableName
DECLARE cursorFields CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT sc.NAME as 'Field_name',
case when t.Name in ('char', 'varchar', 'nvarchar')
then t.Name + '(' + cast(sc.max_length/2 as nvarchar) + ')'
else
case when t.Name in ('numeric')
then t.Name + '(' + cast(sc.precision as nvarchar) + ',' + cast(sc.scale as nvarchar) + ')'
else t.Name
end
end as 'Data_type',
case when sc.is_nullable=1 then 'null' else 'not null' end as 'Nullable'
FROM sys.tables st
INNER JOIN sys.columns sc ON st.object_id = sc.object_id
INNER JOIN sys.types t ON sc.system_type_id = t.system_type_id
WHERE t.Name != 'sysname'
AND st.name = @tableName
ORDER BY 1, 2
OPEN cursorFields
FETCH NEXT FROM cursorFields INTO @fieldName, @fieldType, @fieldNullable
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT '-- ' + @fieldName + ' (' + @fieldType + ', ' + @fieldNullable + ')'
FETCH NEXT FROM cursorFields INTO @fieldName, @fieldType, @fieldNullable
END
CLOSE cursorFields
DEALLOCATE cursorFields
PRINT '--'
FETCH NEXT FROM cursorTables INTO @tableName
END
CLOSE cursorTables
DEALLOCATE cursorTables
END