Clause SOURCEDEFS et réplication DDL avec GoldenGate

La clause SOURCEDEFS pour ceux qui ne la connaitraient pas déjà, permet dans GoldenGate de gérer la réplication entre deux tables de structures différentes (ordre différent des colonnes, noms différents, ou colonnes additionnelles entre la source et la cible) comme par exemple :
COLMAP
Cette clause SOURCEDEFS est  utilisée sur la base cible de la réplication et doit contenir en paramètre un fichier contenant la structure des objets à répliquer. Ce fichier est à générer sur la base source à l’aide de l’utilitaire defgen et doit être copié vers la cible dans le sous-répertoire dirdef pour y être exploité.

Sur la source:
edit param defgen
defsfile ./dirdef/structure.def , purge
userid goldengate , password goldengate
table SCHEMA.TABLE ;
$ ./defgen paramfile ./dirprm/defgen.prm
$ scp ./dirdef/structure.def  <cible>:$GGDIR/dirdef/
Sur la cible :
edit param rep_test
...
...
SOURCEDEFS ./dirdcef/structure.def
...
MAP SCHEMA.TABLE , TARGET.TABLE , COLMAP(USEDEFAULTS) ;

La clause SOURCEDEFS est riche et permet d’adresser tous types de situations de réplication, même les plus complexes, mais son utilisation est incompatible avec les clauses de réplication des ordres DDL.
En cas d’utilisation du mot-clé SOURCEDEFS avec une quelconque tentative de réplication des ordres DDL (ex: DDL INCLUDE MAPPED), votre process plantera avec un message d’erreur comme celui-ci :

ERROR OGG-00406 DDL replication is not compatible with SOURCEDEFS parameter.

Mais si, comme il m’est arrivé récemment, vous devez effectuer une réplication DML + DDL sur des tables dont les structures diffèrent, voici une façon de procéder qui utilise le mot-clé ASSUMETARGETDEFS et qui fonctionne avec toutefois les quelques restrictions que voici.
L’option ASSUMETARGETDEFS comme son nom l’indique est normalement utilisée lorsque les structures des tables répliquées sont identiques, mais elle fonctionne également si l’on précise dans la clause COLMAP les affectations aux colonnes supplémentaires comme par exemple :

MAP SCHEMA.TABLE , TARGET SCHEMA.TABLE , COLMAP (USEDEFAULTS, COL1 = @GETENV('GGHEADER','COMMITTIMESTAMP')) ;

Là où le mapping des colonnes se fait par rapport au nom des champs avec l’option SOURCEDEFS, celui de l’option ASSUMETARGETDEFS se fait par rapport à la position des champs uniquement.
Il faut donc s’assurer, pour que la réplication fonctionne correctement, que les champs additionnels soient systématiquement placés en dernières positions, ce qui, du coup, pose problème en cas de réplication d’ordres DDL (ex: ajout d’une colonne sur la table source).
Pour adresser ce dernier point, il a fallu trouver une procédure de repositionnement des champs pour que les champs supplémentaires restent toujours en dernière position.
Pour effectuer ce repositionnement des champs sur une table A,B,C,D à laquelle on ajoute une colonne E et répliquée vers A,B,C,D,TIMESTP, en version Oracle 11gR2 ou version inférieure, voici la procédure à suivre :

ALTER TABLE SCHEMA.TABLE ADD E NUMBER(10) ;
ALTER TABLE SCHEMA.TABLE RENAME COLUMN TIMESTP TO TIMESTP_OLD ;
ALTER TABLE SCHEMA.TABLE ADD TIMESTP TIMESTAMP ;
UPDATE SCHEMA.TABLE SET TIMESTP = TIMESTP_OLD ;
COMMIT ;
ALTER TABLE SCHEMA.TABLE DROP COLUMN TIMESTP_OLD ;

On peut aussi faire BEAUCOUP PLUS SIMPLE en utilisant la nouvelle fonctionnalité Oracle 12c : LA COLONNE INVISIBLE, en exécutant les commandes suivantes :

ALTER TABLE SCHEMA.TABLE MODIFY TIMESTP INVISIBLE ;
ALTER TABLE SCHEMA.TABLE ADD E NUMBER(10) ;
ALTER TABLE SCHEMA.TABLE MODIFY TIMESTP VISIBLE ;

Il y a du bon dans la version 12c, elle va vraiment dans le sens de la simplification,  vous ne trouvez pas ?