Bonjour,
Je suis en train de travailler sur l'alimentation d'un infocentre à partir d'une base de données relationnelle.
Mon programme doit gérer des flux en différentiel.
J'ai donc opté pour une base tampon dans laquelle j'archive, pour chaque export des données, l'ensemble des données "telles qu'elles devraient être" dans l'infocentre.
Puis avec une vue, je filtre les lignes qui sont effectivement différentes d'une "version" à l'autre.
Voici un exemple simplifié :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 create table tampon.dbo.client ( version tinyint not null, id int not null, nom varchar(30) null, prenom varchar(30) null, primary key (version, id) ); go -- Avant d'alimenter un nouveau jeu de données, on augmente l'âge des données déjà présentes (ouais je sais, c'est mal, je met à jour la clé primaire) update tampon.dbo.client set version = version + 1; -- On récupère les données à synchroniser insert into tampon.dbo.client (version, id, nom, prenom) select 1, c.id, n.nom, p.prenom from client c left outer join nom n on n.id = c.nom_id and c.politiquementcorrect = 1 left outer join prenom p on p.id = c.prenom_id and p.politiquementcorrect = 1 where c.statut = 'ACTIF';
Jusque là, tout va bien.
J'ai donc à chaque fois la liste de tous mes clients actifs, avec leurs noms et prénoms à partir du moment où ils sont politiquement correct.
Maintenant, on passe à la vue, dans la base "tampon" :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 create view dbo.v_client with schemabinding as select 'NEW' statut, c1.id, c1.nom, c1.prenom from dbo.client c1 where c1.version = 1 and not exists (select null from dbo.client c2 where c2.version = 2 and c2.id = c1.id) union all select 'DEL' statut, c1.id, c1.nom, c1.prenom from dbo.client c1 where c1.version = 2 and not exists (select null from dbo.client c2 where c2.version = 1 and c2.id = c1.id) union all select 'UPD' statut, c1.id, c1.nom, c1.prenom from dbo.client c1 inner join dbo.client c2 on c2.version = 2 and c2.id = c1.id where c1.version = 1 and ( c1.nom <> c2.nom or c1.prenom <> c2.prenom );
Sauf que là, la partie "UPD" ne fonctionne pas, à cause des NULL
Du coup, pour chaque colonne, je dois mettre ce code à ralonge :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 c1.val <> c2.val or (c1.val is null and c2.val is not null) or (c1.val is not null and c2.val is null)
Seul souci :
1/ C'est illisible
2/ C'est ultra redondant
3/ J'ai une dizaine de tables à synchroniser avec jusqu'à une cinquantaine de colonnes pour certaines
4/ Je ne veux pas remplacer ce code par des "isnull(val, '')" et "isnull(val, 0)" car c'est pas spécialement plus lisible ni concis, mais en plus ça demande à se poser la question du type de chaque colonne, mais surtout si demain je place des index sur ces tables pour améliorer les performances de la vue, ça ne pourra pas utiliser les index
Bref : comment faire ?
Question subsidiaire : la méthode adoptée vous semble-t-elle adaptée au besoin ?
Partager