none
Sincronizar base de datos SQL RRS feed

  • Pregunta

  • Hola! Tengo un problema. Tengo dos bases de datos "iguales", una la de pruebas y la otra es la que se usa. Antes de que se implementara el sistema, hacia un backup de la de prueba y restauraba sobre la que se iba a usar, pero ahora esa base no se puede borrar mas y hay que actualizarla desde la de pruebas. Probando con SQL Management Studio 2014 solo logro que haga INSERT, pero no UPDATE, yo necesito agregar nuevos registros, si los hay, y actualizar los existentes. Alguna forma? Gracias!
    lunes, 21 de diciembre de 2015 14:12

Respuestas

  • No voy a empezar un debate.

    Si tanto quieren esto porque no usan mirror, merge replication, transactional replication o log shipping, algunos no te daran acceso a la informacion en el secundario como mirror o log shipping pero las replicas haran lo que pides sin necesidad de entrar a codigo.  

    lunes, 21 de diciembre de 2015 22:36
  • Hola Enrique AA,

    Pero no hay debate que iniciar, el punto es centrarse en el contexto del hilo:

    • Se sugiere el uso de la clausula INTO para recrear las tablas y cargar datos.
    • Angel comenta tener cuidado en el uso de INTO porque no recrea fielmente la estructura de la tabla.
    • Tú nos comentas que no hay problema, "que un constraint menos no hace mayor diferencia".
    • Yo replico en que si hay problema porque al recrearse la tabla de manera incompleta al origen, ambos contenedores terminan siendo parcialmente distintos.


    Respecto a  mirror, merge replication, transactional replication o log shipping y demás, pues sería bueno que lo sugierás si consideras que es una buena opción, yo sólo apunte a observe algo que equivocadamente afirmaste.

    lunes, 21 de diciembre de 2015 22:49

Todas las respuestas

  • Hola avechuche,

    Puedes hacer uso de Merge para insertar los registros que faltan y actualizar los que ya existen, te dejo un script de ejemplo para que tengas claro como afrontar lo que requieres:

    /*Creamos una variable de tipo tabla como ejemplo para el manejo de Merge*/
    DECLARE @TablaOrigen table (ID int, nombre nvarchar(100), edad tinyint);
    DECLARE @TablaDestino table (ID int, nombre nvarchar(100), edad tinyint);
    
    /*Insertamos datos en la tabla Destino*/
    INSERT INTO @TablaDestino VALUES
    	(1, 'JUAN', 20),
    	(2, 'MARCOS', 30),
    	(3, 'PAUL', 40);
    
    /*Insertamos datos en la tabla Origen*/
    /*En este caso insertaremos un regostro adicional y modificaremos el registro con ID = 2*/
    INSERT INTO @TablaOrigen VALUES
    	(1, 'JUAN', 20),
    	(2, 'MARCOS GABRIEL', 30),
    	(3, 'PAUL', 40),
    	(4, 'GABRIEL', 50);
    
    /*Implementamos Merge*/
    MERGE @TablaDestino AS Destino
    USING (SELECT ID, nombre, edad FROM @TablaOrigen) AS Origen
    ON (Destino.ID = Origen.ID)
    WHEN NOT MATCHED THEN
    	INSERT (ID, nombre, edad)
    	VALUES (Origen.ID, Origen.nombre, Origen.edad)
    WHEN MATCHED THEN
    	UPDATE SET nombre = Origen.nombre, edad = Origen.edad;
    
    /*Revisamos los datos de ambas tablas para corroborar que tienen los mismos registros*/
    SELECT * FROM @TablaOrigen;
    SELECT * FROM @TablaDestino;
    

    lunes, 21 de diciembre de 2015 15:14
  • Por otro lado, si lo que requieres es sincronizar los datos de todas las tablas de tu base de datos existen aplicaciones que te permiten hacerlo, una de ellas es Visual Studio, Menu Herramientas > SQL Server > Nueva comparación de datos. Incluso si has cambiado de estructura puedes hacer un merge para igualar tanto diseño como datos.
    lunes, 21 de diciembre de 2015 15:25
  • Por otro lado, si lo que requieres es sincronizar los datos de todas las tablas de tu base de datos existen aplicaciones que te permiten hacerlo, una de ellas es Visual Studio, Menu Herramientas > SQL Server > Nueva comparación de datos. Incluso si has cambiado de estructura puedes hacer un merge para igualar tanto diseño como datos.

    Gracias Willams por tu ayuda. Estaba mirando el primer ejemplo, pero por la cantidad "infinita" de datos que tengo, creo que voy a estar un año creando el script para todas las tablas. Por otro lado, lo que recien me doy cuenta: La DB_DESTINO tiene 3 o 4 tablas que no se van a tocar externamente, solo se van a modificar cuando el usuario haga un cambio de su perfil (por ejemplo). En cuanto a las otras tablas, se podrian eliminar tranquilamente y volver a cargar los datos, porque almacenan configuración que solo otros admin y yo podemos modificar. Me pareceria menos engorroso, total que esperen un poco más para la actualización de la DB.

    Con respecto a lo de Visual, me es imposible, porque no tengo la DB_DESTINO actualizada en todo momento, si hago eso, despues tienen que restaurar y nada me asegura que la DB no fue modificada de nuevo.

    Hay alguna forma de borrar esas tablas, crearlas de nuevo? No estoy seguro como respondera el SGBD al encontrar una FK, si me va a dejar borrar la tabla y crearla de nuevo. Gracias de nuevo!

    lunes, 21 de diciembre de 2015 15:47
  • No entiendo el porque no te sirve del todo las herramientas de comparación de datos de VS, la herramienta compara los datos de origen y destino y ante las diferencias ejecuta los comandos necesarios para igualar ambos orígenes, no requieres de ninguna restauración.

    Si tienes una edición de pago de SQL Server puedes hacer uso de Integration Services para definir un flujo de sincronización de datos.

    Finalmente, si concluyes en que más rápido es borrar y crear de nuevo las tablas pues debes de cuidar de eliminar primero las tablas que no hagan referencia a otras, en ese orden, algo como lo siguiente bastaría:

    /*Borro tablas*/
    DELETE BDDestino..DetalleFactura;
    DELETE BDDestino..CabeceraFactura;
    DELETE BDDestino..Clientes;
    
    /*Creo las tablas e inserto los datos*/
    SELECT * INTO BDDestino..Clientes FROM BDOrigen..Clientes;
    SELECT * INTO BDDestino..CabeceraFactura FROM BDOrigen..CabeceraFactura;
    SELECT * INTO BDDestino..DetalleFactura FROM BDOrigen..DetalleFactura;


    lunes, 21 de diciembre de 2015 15:56
  • Hola avechuche

    Tene ojo con el comando SELECT * INTO!!!

    Porque una vez confiado de lo que hacia ejecute ese comando y no crea la estructura tal cual a la tabla origen. Aun no pude probar ese comando. Pero me paso en particular que por ejemplo que no me creo los CHECK de la tabla. Y puede ocurrir que tampoco te cree los FK, no estoy de todo seguro que cosas te pueden llegar a faltar, como dije tengo que probarlo.

    Si lo usas anda chequeando si las estructuras son iguales.

    Tal vez te convenga generar el script con las estructuras de las tablas y hacer una consulta dinámica para que no te mates haciendo los INSERT de todas las tablas como mencionaste.

    Saludos

    lunes, 21 de diciembre de 2015 18:57
  • Saludos Angel

    El comando "select * into" replica la estructura y datos mas no los constrainns que existan, lo que mencionas son constrains y estan en lo que no copia no veo porque el comando digas que no hace una copia igual

    lunes, 21 de diciembre de 2015 21:44
  • Angel, es cierta la observación que haces, la cláusula  INTO no transfiere a la tabla destino los triggers, índices ni restricciones (entiendose por restricciones las Primary Key, Foreign Key, Check, Unique Key, NULL/NOT NULL), esto para tomar muy en consideración.

    Enrique, por lo mencionado anteriormente - y observado por ángel - la cláusula INTO no clona la estructura de la tabla origen en la tabla destino, la tabla destino no es la misma, no es igual, no sólo basta los datos sino que la tabla se recree tal como el origen.

    Avechuche, sigo considerando una opción viable VS ya que no sólo podrás "empatar" estructura sino además datos, piénsalo y nos comentas que decisión tomaste.

    lunes, 21 de diciembre de 2015 22:04
  • No voy a empezar un debate.

    Si tanto quieren esto porque no usan mirror, merge replication, transactional replication o log shipping, algunos no te daran acceso a la informacion en el secundario como mirror o log shipping pero las replicas haran lo que pides sin necesidad de entrar a codigo.  

    lunes, 21 de diciembre de 2015 22:36
  • Hola Enrique AA,

    Pero no hay debate que iniciar, el punto es centrarse en el contexto del hilo:

    • Se sugiere el uso de la clausula INTO para recrear las tablas y cargar datos.
    • Angel comenta tener cuidado en el uso de INTO porque no recrea fielmente la estructura de la tabla.
    • Tú nos comentas que no hay problema, "que un constraint menos no hace mayor diferencia".
    • Yo replico en que si hay problema porque al recrearse la tabla de manera incompleta al origen, ambos contenedores terminan siendo parcialmente distintos.


    Respecto a  mirror, merge replication, transactional replication o log shipping y demás, pues sería bueno que lo sugierás si consideras que es una buena opción, yo sólo apunte a observe algo que equivocadamente afirmaste.

    lunes, 21 de diciembre de 2015 22:49