Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

replica tra due tabelle con nomi diversi e con nomi di colonna diversi. È possibile creare tale replica

Apparentemente, la risposta è:"Quando definisci l'articolo, dovrai impostare il @vertical_partition parametro su true e quindi aggiungi le colonne desiderate con sp_articlecolumn ."

Tuttavia, devo chiederti perché lo stai facendo. La replica nella mia mente non è uno strumento generale per spostare i dati tra database a differenza di database, ma per mantenere sincronizzati due database identici.

Altre idee di brainstorming:

  • Puoi creare una nuova tabella di origine che corrisponda alla tabella di destinazione e utilizzare un trigger per mantenere sincronizzata la tabella di origine.
  • Spingi la tabella di origine intatta alla destinazione ed esegui l'UNIONE nel database di destinazione.
  • La replica potrebbe non essere davvero la soluzione giusta, qui. Quali sono le regole e i requisiti aziendali che richiedono che ciò avvenga? Hai pensato di utilizzare SSIS?
  • Se è necessario che le due tabelle siano sempre sincronizzate esattamente, qual è il canale delle modifiche alla tabella di origine:un'applicazione? Sembra quasi che la tua applicazione abbia bisogno di un nuovo livello di astrazione, un livello di scrittura dei dati che sappia come scrivere su due sorgenti contemporaneamente.

Cercare di mantenere i dati sincronizzati tra due database diversi può essere un problema. Possono esserci tutti i tipi di problemi sottili con condizioni di gara, mancanza di transazioni distribuite (che influiscono sulla coerenza e sulla risposta agli errori), problemi con le soluzioni alternative create per affrontare la mancanza di transazioni distribuite e così via e così via. Puoi invece creare un server collegato e alcune viste che rendano effettivamente i dati in un database accessibili in tempo reale dall'altro?

Per favore, dicci di più sulle tue esigenze e perché devi farlo.

Aggiorna

Se stai seguendo il percorso di aggiornamento manuale, tieni presente che non puoi applicare le operazioni di inserimento, aggiornamento ed eliminazione di un periodo di tempo in blocco. Devi applicarli uno alla volta, in ordine . Se invece stai lavorando con lo stato corrente anziché operazioni sui dati intermedi, puoi eseguire tutte le righe contemporaneamente. Ti mostrerò l'esempio di MERGE, non quello di riproduzione della cronologia.

BEGIN TRAN;

DELETE D
FROM LinkedServer.dbo.Dest D WITH (TABLOCKX, HOLDLOCK)
WHERE
   NOT EXISTS (
      SELECT *
      FROM Source S
      WHERE D.Key = S.Key
   );

UPDATE D
SET
   D.Col1 = S.Col4,
   D.Col2 = S.Col5,
   D.Col3 = S.Col6,
   D.Col4 = S.Col7,
FROM
   LinkedServer.dbo.Dest D
   INNER JOIN Source S ON D.Key = S.Key
WHERE
   D.Col1 <> S.Col4
   OR EXISTS (
      SELECT D.Col2, D.Col4
      EXCEPT
      SELECT S.Col3, S.Col6
   ); -- or some other way to handle comparison of nullable columns

INSERT LinkedServer.dbo.Dest (Col1, Col2, Col3)
SELECT Col4, Col5, Col6
FROM Source S WITH (TABLOCK, HOLDLOCK)
WHERE
   NOT EXISTS (
      SELECT *
      FROM LinkedServer.dbo.Dest D
      WHERE S.Key = D.Key
   );

COMMIT TRAN;

Potrebbe essere meglio eseguire il push dell'intera tabella ed eseguire l'operazione di unione sul server di destinazione.

I suggerimenti di blocco che ho inserito nella prima query sono importanti se si desidera ottenere uno snapshot point-in-time coerente. Se non ti interessa, elimina i suggerimenti per il blocco.

Se trovi che gli aggiornamenti sul server collegato sono lenti, invia l'intera tabella in un unico pezzo a una tabella di staging temporanea sul server remoto ed esegui MERGE in uno script interamente sul server remoto.