2010-01-25 38 views
9

SQL Gurus -Comparación de procedimientos almacenados en varias bases de datos (SQL Server)

Nuestra arquitectura consiste en varias bases de datos de clientes para una base de código común. Cuando implementamos cambios en la base de datos, los scripts deben ejecutarse de forma conjunta con cada base de datos.

Debido a problemas de implementación, ha habido ocasiones en que nuestros procedimientos almacenados no se sincronizaron entre sí. Me gustaría crear una secuencia de comandos para devolver estos procedimientos mimados para garantizar que tengamos copias sincronizadas de nuestras bases de datos después de la implementación.

¿Es posible comparar dos o más bases de datos, haciendo que un script vea todos los procedimientos entre dos bases de datos, y devuelva las discrepancias?

algo en el sentido de:

DATABASE_1 | DATABASE_2 | MISMATCHED_PROCEDURE | DATABASE_1_MODIFY_DATE | DATABASE_2_MODIFY_DATE 
Customer_1 | Customer_2 | sp_get_names   | 1/1/2010    | 1/2/2010 
Customer_1 | Customer_2 | sp_add_person  | 1/5/2010    | 1/6/2010 

Como beneficio adicional, ¿sería posible tener el guión sincronizar automáticamente las bases de datos mediante la aplicación de la secuencia de comandos más reciente a la secuencia de comandos fuera de fecha?

¡Muchísimas gracias!

Respuesta

15

Hay muchas herramientas para hacer esto. Uno de los mejores es Red-Gate SQL Compare. Otra muy buena alternativa es usar Visual Studio Database Professional para administrar su esquema de base de datos. Entre otras cosas, hará muy buenas comparaciones de esquemas.

+4

SQL Compare es exactamente lo que me vino a la mente, ¡gran sugerencia! http://www.red-gate.com/products/SQL_Compare/index.htm – D3vtr0n

+2

Excelente herramienta, y no solo esta, todo de Redgate es de primera categoría. –

+0

@marc_s - De acuerdo. Casi cualquier cosa de Red-Gate es oro. –

8

Si no tiene SQL Comparar o el sistema de equipo de Visual Studio para los arquitectos de datos DB (del tipo del ...) jugar con esta ... SQL 2005 y hasta

select t1.name,t1.modify_date,t2.modify_date 
from Database1.sys.procedures t1 
join Database2.sys.procedures t2 on t1.name = t2.name 
and object_definition(t1.object_id) <> object_definition(t2.object_id) 
1

respuesta simplista, pero una caída y crear script en todos los procedimientos sería muy fácil y efectivo.

3

SQL de la Puerta Roja Comparar es la solución perfecta. Sin embargo, si usted no puede pagar su coste no es un muy buen software que es libre: SQL de Star Inix Comparar http://www.starinix.com/sqlcompare02.htm

+0

no pulido, pero realmente es una pequeña herramienta ... considerando que es gratis. Hace un buen trabajo para las comparaciones básicas de dbs, pero tiene que tener cuidado con las cosas de spam de cnet en la instalación. – Dave

+0

La URL que figura en la lista no funcionó para mí. Sin embargo, la URL http://starinix.com/sqlcompare02.htm funcionó. –

11

Puede identificar qué procedimientos (y otros objetos con una ligera modificación) son diferentes utilizando la secuencia de comandos abajo.

Para sincronizar bases de datos, puede intentar ApexSQL Diff. Es similar a SQL Compare de Red Gate.

select S1.name [Db1_Schema], O1.name as [Db1_Object], O1.modify_date, 
S2.name [Db1_Schema], O2.name as [Db1_Object], O2.modify_date 
from database.sys.all_objects O1 
inner join database2.sys.all_objects O2 on O1.name = O2.name 
inner join database.sys.syscomments C1 on O1.object_id = C1.id 
inner join database2.sys.syscomments C2 on O2.object_id = C2.id 
inner join database.sys.schemas S1 on O1.schema_id = S1.schema_id 
inner join database2.sys.schemas S2 on O2.schema_id = S2.schema_id 
where C1.text <> C2.text and 
-- remove the line below if you want to search all objects 
O1.type = 'P' 
+0

gracias ... funciona ... pero cuando corro en dos entornos obtengo más registros. 107 procedimientos estaban disponibles en cada db, pero cuando la consulta anterior se ejecutó recibo más de 1,00,000 registros ... sugiero – Smart003

+0

Este código dice que todos mis SP son diferentes (que no), es decir, la comparación C1.text < > C2.text es siempre cierto. Probé object_definition (t1.object_id) <> object_definition (t2.object_id) de la respuesta a continuación y lo ordené – DJDave

1

Si desea comparar todos los procedimientos almacenados de ambas bases de datos y nombres de salida de los que no existen en el otro, a continuación, utilizar la siguiente. Tenga en cuenta que esto no verifica la definición de los procedimientos almacenados solo su nombre, pero también hay una manera de verificarlo.

-- Declare 2 variable names to hold the name of the databases 
DECLARE @DB1 varchar(50) 
SET @DB1 = 'nameOfDb1' 
DECLARE @DB2 varchar(50) 
SET @DB2 = 'nameOfDb2' 
EXEC('SELECT 
     t1.name, 
     t2.name 
     FROM ' 
     + @DB1 +'.sys.procedures t1 
     FULL OUTER JOIN ' 
    + @DB2 + '.sys.procedures t2 
     on t1.name = t2.name 
     where t1.object_id IS NULL 
     OR t2.object_id IS NULL') 
1

Sí, las cosas Redgate es grande, pero eso es lo que he hecho para comparar los procedimientos almacenados en dos bases de datos diferentes: 1 - Scripted todo procedimiento almacenado en archivos separados. Puede hacerlo a través del asistente de Microsoft SQL Server Management Studio. 2 - Hice lo mismo desde la otra base de datos con la que me comparo. 3 - Comenzó KDiff3 que es gratis, creo. 4 - Le dio los dos directorios que necesita para recorrer. 5 - Ahora inspeccione sus resultados haciendo doble clic donde vea el rojo y el panel a continuación le dirá las diferencias.

¡Hecho!

0

El siguiente Procedimiento puede encontrar las diferencias de Funciones, Procedimientos, Disparadores en dos bases de datos diferentes. Pase los nombres de la base de datos como parámetros.

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE Specific_name = 'SP_SCRIPTDIFF') 

DROP PROCEDURE DBO.SP_SCRIPTDIFF 

GO 

CREATE PROCEDURE [dbo].SP_SCRIPTDIFF 

@DBNAME1 SYSNAME, 
@DBNAME2 SYSNAME 

AS 

/* 
DATE  : 2016/07/29 
AUTHOR : SEENI 
OBJECTIVE : TO COMPARE THE FUNCTIONS, PROCEDURES AND TRIGGERS IN TWO DIFFERENT DATABASES, PASS NAME OF DATABASE1, AND DATABASE2 AS INPUTS. 
*/ 

BEGIN 

SET NOCOUNT ON 

Exec ('select DISTINCT O1.name as [ObjectName], O1.modify_date As DateIn_'[email protected]+', O2.modify_date As DateIn_'[email protected]+',o1.type as Type from '+ 
@DBNAME1+'.sys.all_objects O1 join '+ @DBNAME2+'.sys.all_objects O2 on O1.name = O2.name and O1.type = O2.type join '+ 
@DBNAME1+'.sys.syscomments C1 on O1.object_id = C1.id join '+ @DBNAME2+'.sys.syscomments C2 on O2.object_id = C2.id join '+ 
@DBNAME1+'.sys.schemas S1 on O1.schema_id = S1.schema_id join '+ @DBNAME2+'.sys.schemas S2 on O2.schema_id = S2.schema_id 
where C1.text <> C2.text and c1.colid = c2.colid and O1.Type in (''FN'',''P'',''T'') And o1.Is_Ms_Shipped = 0 Order by O1.type,ObjectName') 

RETURN 

END 

GO 
Cuestiones relacionadas