SQL Server MDS – Suppression des lignes désactivées d’un Model

Amis utilisateurs de MDS bonjour !

Il est bon de savoir que, pour des raisons compréhensibles d’historique et de récupération de données, MDS ne fait que désactiver les lignes supprimées via les interfaces Web et Excel. Ça soulage toujours de savoir qu’on pourra rattraper l’éventuelle grosse bêtise si elle a lieu…

Le problème vient quand un utilisateur découvre qu’un membre de l’entité qu’il gère n’est plus utilisé. Pour des raisons de lisibilités, il décide de supprimer la ligne et publie :

ImageSuppression

Côté MDS, chaque entité possède une clef primaire en la présence du champ « Code », l’enregistrement possédant ce code est ici désactivé.

Mais, si ce code doit à nouveau être utilisé, l’utilisateur rencontre le message d’erreur suivant :

ImageMessageDoublon

Vous vous en doutez: la nouvelle ligne rentre en conflit d’unicité avec celle supprimée, préservée dans la base. Tout aurait pu être parfait si nous avions eu la possibilité de visualiser ces lignes désactivées depuis les interfaces auxquelles un utilisateur classique (non admin) aurait accès, mais ce n’est pas le cas.

A l’heure actuelle, l’utilisateur est redirigé via un message d’erreur vers un administrateur pour retirer le membre, pas vraiment self-service…
Il existe 2 solutions pour résoudre le problème :
– Restaurer la ligne depuis l’interface Web avec un compte ayant les accès à la gestion des versions :

ImageRestauration

– Supprimer les lignes depuis la table de staging :

Les tables de staging, sont des tables intermédiaires par lesquelles vous pouvez passer pour ajouter, modifier ou supprimer des lignes de vos entités. Chaque entité possédera sa propre table de staging. Vous pourrez trouver la correspondance entre vos entités et vos table de staging dans la table système « MDSDB.mdm.viw_SYSTEM_TABLE_NAME »

Pour chaque entité, MDS mettra à disposition une procédure pour transférer les données de la table de staging dont le nom sera au format « stg.udp_[MaTableStaging] »

Nous pouvons donc utiliser une procédure stockée qui comprendra 3 étapes principales :

  • Insertion des données dans la table de staging avec les paramètres adéquats
  • Appel de la procédure MDS pour transférer les données de la table de staging vers la table source de l’entité
  • La validation des données
​CREATE PROCEDURE [mds].[DeleteUnactiveRowsFromEntity]
@EntityTableName VARCHAR(50)
, @StagingLeafName VARCHAR(50)
, @Model_Id INT
AS
BEGIN

DECLARE @BatchTagText AS VARCHAR(50) = 'Suppression Automatique du ' + CAST(CAST(getdate() AS Date) AS VARCHAR)
DECLARE @SQLCommand VARCHAR(MAX)

SET @SQLCommand =
'INSERT INTO [MDSDB].[stg].[' + @StagingLeafName + ']
([ImportType]
,[ImportStatus_ID]
,[BatchTag]
,[Code]
)
SELECT 6 AS [ImportType] --6 pour suppression permanente des données
,0 AS [ImportStatus_ID]
,'''+ @BatchTagText+ '''
,[Code]
FROM [MDSDB].[mdm].' + @EntityTableName
+ ' WHERE Status_ID = 2'

EXEC (@SQLCommand);

DECLARE @Version_ID INT
DECLARE @Version_Name VARCHAR(50)

SELECT @Version_ID = ID
, @Version_Name = Name
FROM MDSDB.mdm.viw_SYSTEM_SCHEMA_VERSION V
WHERE Model_ID = @Model_ID
AND V.ID = (SELECT MAX(ID)
FROM MDSDB.mdm.viw_SYSTEM_SCHEMA_VERSION V
WHERE Model_ID = @Model_ID)

--Lancement du lot de MàJ des données
SET @SQLCommand =
'EXEC MDSDB.[stg].[udp_' + @StagingLeafName + ']
@VersionName = ''' + @Version_Name +'''
,@LogFlag = 1
,@BatchTag = ''' + @BatchTagText + '''' ;
EXEC (@SQLCommand);

--Validation des données
DECLARE @User_ID INT

SET @User_ID = ( SELECT ID
FROM MDSDB.mdm.tblUser u
WHERE u.UserName = SUSER_NAME())
--Validation des données insérées ou modifiées dans le modèle
EXECUTE MDSDB.mdm.udpValidateModel @User_ID, @Model_ID, @Version_ID, 1

END

Nous pourrons utiliser une procédure chapeau qui englobera la totalité des entités d’un modèle passé en paramètre :

CREATE PROCEDURE [mds].[DeleteUnactiveRowsFromModel]
@Model_Name varchar(50)
AS
BEGIN
DECLARE @Model_Id INT

--Récupération de l'ID du modèle avec la dernière version
SET @Model_ID = ( SELECT TOP 1 Model_ID
FROM MDSDB.mdm.viw_SYSTEM_SCHEMA_VERSION
WHERE Model_Name = @Model_Name)

DECLARE @ListEntities TABLE ( EntityName varchar(50)
, EntityTableName varchar(50)
, StagingLeafName varchar(50)
, NumLigne INT)

--Récupération de la liste d'entités du modèle
INSERT INTO @ListEntities
SELECT EntityName
, EntityTableName
, StagingLeafName
, ROW_NUMBER() OVER (ORDER BY EntityTableName) AS NumLigne
FROM MDSDB.mdm.viw_SYSTEM_TABLE_NAME
WHERE Model_ID = @Model_Id

DECLARE @NbEntities INT = (SELECT MAX(NumLigne) FROM @ListEntities)
DECLARE @Compteur INT = 1

--On boucle pour chaque entité de notre modèle
WHILE @Compteur <= @NbEntities
BEGIN
DECLARE @EntityTableName varchar(50)
, @StagingLeafName varchar(50)

SELECT @EntityTableName = EntityTableName
,@StagingLeafName = StagingLeafName
FROM @ListEntities
WHERE NumLigne = @Compteur

--Appel de notre Proc, créée plus haut, en passant l'entité courante de la boucle
EXEC mds.DeleteUnactiveRowsFromEntity @EntityTableName, @StagingLeafName, @Model_Id

SET @Compteur = @Compteur + 1
END

Un job pourra être appelé toute les 15/30/60/90min suivant la patience des utilisateurs.

Certes, il s’agit de code SQL dynamique, pas forcément élégant, mais ça a le mérite de faire le travail en redonnant (un peu) la main à l’utilisateur, avec le délai d’appel du job que vous aurez paramétré.
La procédure est à utiliser avec parcimonie, certains environnements demanderont de conserver l’historique. Par exemple, pour une entité avec de nombreux champs, il sera plus simple de restaurer un membre plutôt que de le recréer.

Le choix est à l’utilisateur.

Pas de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *