Pergunta

Estamos prestes a executar side-by-side testes para comparar um sistema legado com uma nova versão brilhante. Temos uma tabela de banco de dados Oracle, A, que armazena dados para o sistema legado e uma tabela equivalente, B, que armazena dados para o novo sistema, portanto, para a duração do teste, o banco de dados é desnormalizada. (Além disso, o sistema legado e tabela A são fixos - nenhuma alteração permitida)

O que eu quero fazer é permitir que as operações DML não frequentes sobre A se propaguem para B, e vice-versa. Comecei com um par de gatilhos para fazer isso, mas bateu o problema óbvio que quando os gatilhos executar, as tabelas são mutação, e uma exceção é lançada.

Existe uma maneira padrão de lidar com esta questão? Eu li diferentes relatórios sobre se deve ou não usar DBMS_SCHEDULER é o caminho a percorrer ...

Obrigado,

Andy

Update: Eu acabei chickening de toda a questão e garantiu que todos os procedimentos armazenados essa atualização A, também atualizar B, e vice-versa.

Eu marquei a resposta de Quassnoi como aceite, porque eu seguir suas sugestões, se depara com o mesmo problema no futuro.

Eu tenho marcado resposta de JosephStyon, porque eu brevemente tenho coisas trabalhando adicionando dois insert / update gatilhos nível de instrução em tabelas A e B, em seguida, fazendo o seu procedimento de fusão usando A ou B como tabela mestre, dependendo do gatilho RAN (embora primeiro eu verifiquei que a tabela de destino seria alterado pela fusão, earlying se não).

Foi útil?

Solução

Eu criar A e B como vistas sobre uma mesa única normalizada (ou denormalized), e criou um gatilho INSTEAD OF sobre esses pontos de vista para operações de alça DML.

Se os planos de consulta importa, é melhor manter duas cópias de tabelas: A_underlying e B_underlying e criar as vistas apenas como este:

CREATE VIEW A
AS
SELECT  *
FROM    A_underlying

CREATE VIEW B
AS
SELECT  *
FROM    B_underlying

Os predicados serão empurrados para os pontos de vista, e os planos de consulta para tabelas reais e vistas será o mesmo.

Em gatilhos INSTEAD OF mais de dois vista, você deve colocar os dados em ambas as tabelas subjacentes.

Outras dicas

Você DDL realmente quer dizer, não DML?

Com DML você pode ter um olhar para Oráculos multi Mestre Replication para manter as tabelas em sincronia ou você também pode ter um olhar para a ferramenta SymmetricDS para esta finalidade.

Com DDL a única solução que eu estou ciente de é novamente o a Oracle replicação avançada .

Coloque a seguir três declarações em um procedimento armazenado, em seguida, executá-lo como um trabalho agendado tão frequentemente como você gosta:

--Assume that "A" is a master, and "B" needs to be synched

--If no match in "A", delete from "B"
DELETE FROM B
WHERE NOT EXISTS(
                SELECT *
                FROM A
                WHERE A.PRIMARY_KEY = B.PRIMARY_KEY
                );

--If there is a match, but they are different, then update "B"
update 
  (
  select
    a.field1 as new_value1
   ,b.field1 as old_value1
   ,a.field2 as new_value2
   ,b.field2 as old_value2
   ,....
   ,a.fieldN as new_valueN
   ,b.fieldN as old_valueN
  from
    a
   ,b
 where a.primary_key = b.primary_key
 )
set
  old_value1 = new_value1
 ,old_value2 = new_value2
 ,....
 ,old_valueN = new_valueN;


--if the record is new to "A", then insert it into "B"
INSERT INTO B
SELECT *
FROM A 
WHERE NOT EXISTS(
                SELECT *
                FROM B 
                WHERE B.PRIMARY_KEY = A.PRIMARY_KEY
                );

Oracle 10g e acima implementaram Notificação de mudança como um processo assíncrono. É automático e o pacote está incluído com o servidor de instalação do Oracle 10g e acima.

Você pode ver aqui para algumas informações.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top