PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 2024 → Vérifier si un enregistrement a été modifié dans un trigger "Avant"
Vérifier si un enregistrement a été modifié dans un trigger "Avant"
Started by Simon, Feb., 01 2019 6:38 PM - 11 replies
Registered member
8 messages
Posted on February, 01 2019 - 6:38 PM
Bonjour,

Nous travaillons sur projet pour lequel la modification d'enregistrements de fichiers a des conséquences en cascade déclenchées par triggers. Vu les implications, l'idéal serait donc de ne pas déclencher le traitement des conséquences (avec h.AFaire = "A") si les valeurs reçues pour l'enregistrement à modifier ne sont pas différentes des valeurs déjà présentes en bdd.

Les appels HModifie ou HEnregistre pouvant venir d'énormément d'endroits dans le projet, mettre la vérification de leur côté serait très chronophage, c'est pourquoi nous cherchons une solution côté trigger.


On voudrait le fonctionnement suivant :

- le trigger "avant modification" reçoit un enregistrement d'un fichier, par exemple Contact
- si aucune des rubriques du Contact reçu ne diffère du Contact déjà enregistré, on ne veut pas déclencher le trigger de sortie de modification

Pour faire ça, y-a-t il une solution performante ou une fonction magique pour vérifier s'il y a différence, sachant que :
- Beaucoup de noms de fichiers sont concernés (grosse analyse) donc l'idéal serait une solution générique quelque soit le nom du fichier modifié
- Faire un HlitRecherchePremier sur le fichier concerné (par ex "Contact") pour faire la comparaison fait sauter l'enregistrement "Contact" reçu par le trigger
- Les rubriques reçues peuvent êtres des mémos binaires (donc passer par des variants avec HEnregisrementVersVariant pour faire la comparaison ne marchera pas, et de toutes façons comparer deux gros binaires est sans doute trop lourd)


En bref :

- On cherche l'équivalent d'un "..Modifié" mais sur un enregistrement ou une rubrique d'un enregistrement pour voir s'il a effectivement changé avant de traiter le trigger de modification


Si quelqu'un a une idée, nous sommes preneurs !
Registered member
2,566 messages
Popularité : +222 (260 votes)
Posted on February, 03 2019 - 11:22 AM
Bonjour,

Alors tout d'abord, dans les triggers windev, il n'y a pas de notion de deleted/inserted comme en sql server par exemple. Tu n'as donc aucun moyen de savoir ce que contenait ton enregistrement avant sa modification, ce qui fait du trigger tel qu'i est fait, une chose inutile à mon sens.

Cela dit, il peut potentiellement être possible de retrouver tes petits. Je vois 2 solutions à ton problème.

1- Tous tes fichiers ont un id auto qui portent tous le même nom "id" par exemple (ce que je fais personnellement).
2- Les id ou clés ne portent pas toutes le même nom. Dans ce cas, une solution serait de rajouter une table à ton analyse contenant le nom du fichier et le nom de sa clé de recherche afin d'effectuer la recherche sur la bonne clé.

Ensuite, il devient facile de retrouver l'enregistrement de départ grâce à un simple HLitRecherche(). Il te faut bien penser à utiliser HSauvePosition et ce afin de ne pas perdre les modifications de l'enregistrement en cours. Il faudra à mon avis créer une variable de type enregistrement par fichier, ce qui te permettra d'utiliser HCopieEnreg() pour faire tes comparaisons.

Pour comparer les rubriques, il suffit de boucler sur les valeurs de HListeRubrique().

Attention, tout ceci reste de la théorie car comme je te l'ai dit, les triggers Windev étant trop peu évolué à mon goût, je ne les utilise pas, et je n'utilise que les triggers de BDD type SQL Server ou Postgresql.

Espérant que ceci aura pu t'aider.

--
Cordialement,

Philippe SAINT-BERTIN
Registered member
333 messages
Popularité : +9 (13 votes)
Posted on February, 04 2019 - 9:01 AM
Bonjour;
@ Philippe SB.
La solution que j'ai trouvé pour traiter les données avant modification dans un trigger est :
_alias_PS est une Source dede Données

HAlias(MonFichier,_alias_PS)
HChangeNom(_alias_PS,MonFichier..Nom)
HLitRecherchePremier(_alias_PS,_rub_cle_unique,{MonFichier+".ID"})
SI HTrouve(_alias_PS) ALORS

..........

FIN


Cordialement.
Amine.
Registered member
8 messages
Posted on February, 15 2019 - 2:42 PM
Bonjour

J’utilise actuellement la recherche via un alias, mais ca oblige a une lecture data pour comparé,

HLitRechercheDernier(gsdContacts,IDContacts,Contacts.IDContacts)
E1 est un Enregistrement de Contacts=Contacts
E2 est un Enregistrement de Contacts=gsdContacts
SI E1..Contenu=E2..Contenu ALORS H.AFaire="A"

La solution d'une clé hash dans, a voir si le temps de calcule de la clé et plus ou moins performant que la lecture de l'enregistrement.

Merci pour vos raiponces.
Registered member
333 messages
Popularité : +9 (13 votes)
Posted on February, 15 2019 - 6:08 PM
@Simon.
Pouvez nous confirmer que les triggers se déclenchent surement a 100%.
Parfois j'ai remarqué que 1/1000 échec de déclenchement du trigger et ça entraîne beaucoup de problème.

Bon dév.
Amine
Registered member
8 messages
Posted on February, 18 2019 - 9:08 AM
Monsieur AMINE a écrit :
@Simon.
Pouvez nous confirmer que les triggers se déclenchent surement a 100%.
Parfois j'ai remarqué que 1/1000 échec de déclenchement du trigger et ça entraîne beaucoup de problème.

Bon dév.
Amine


Bonjour
Je les utilises beaucoup cotée application avec la fonction HDécritTrigger, je n'est pas constater d'échec jusque là, J'utilise la déclaration de cette façon
HDécritTrigger(Contacts,"HAjoute,HModifie",TriggerContactsAv,hTriggerAvant)
Je n'est pas trop utiliser les Trigger cotée serveur HF.

Attention quand même au point suivent
- La déclaration d'un nouveau Trigger désactive la déclaration précédente sur le même fichier
Registered member
1,623 messages
Popularité : +100 (114 votes)
Posted on February, 18 2019 - 9:41 AM
Hello,

@Mr AMINE @Simon

Au tout début j'utilisais des triggers (SERVEUR pour ma part) et j'ai constaté ce problème d’échec de temps en temps.
Je m'en servais pour générer une clé aléatoire dans chaque enregistrement ajouté et de temps en temps, l'enregistrement était bien fait MAIS le Trigger ne se déclenchait pas. Ca n'arrivait pas souvent (1/1000 semble être une bonne approche) du coup j'ai lâché l'affaire.

C'etait en version 18 de mémoire... HFSQL a peut être été corrigé depuis.
Registered member
333 messages
Popularité : +9 (13 votes)
Posted on February, 18 2019 - 1:01 PM
@ François C.
Je vous confirme qu'ils existent plusieurs problèmes des triggers pour la version 18.
Avec la version 23, le nombre de problème est diminue mais toujours l’échec du déclenchement persiste.
Procedure PS_HONORAIRE_MAJ_SOLDE()
QUAND EXCEPTIONEXCEPTION DANS

SI PAS HFichierExiste(FOURNIS_SOLDE) ALORS
SI PAS HDéclareExterne("FOURNIS_SOLDE.FIC", "FOURNIS_SOLDE") ALORS
RENVOYER Faux
FIN
FIN

SELON Majuscule(H.Action)
CAS "P"
SELON Majuscule(H.FonctionTrigger)
CAS "HAJOUTE"

DEBUT:
HLitRecherchePremier(FOURNIS_SOLDE,COD_FOU,HONORAIRE.COD_FOU)
SI HTrouve() ALORS
FOURNIS_SOLDE.CREDIT += HONORAIRE.MONT_TTC
HModifie(FOURNIS_SOLDE)
SINON
GOTO FIN_TRAIT
FIN
CAS "HMODIFIE"

.....
CAS "HSUPPRIME"
FIN
FIN

FAIRE
FIN_TRAIT:
pLogErreur("PS_REG_FOUR_MAJ_SOLDE")
FIN


Bon dev.
Registered member
2,566 messages
Popularité : +222 (260 votes)
Posted on February, 18 2019 - 3:12 PM
@Charly CANDO: Je tiens à m'excuser auprès de toi, O grand maître du développement. Plus sérieusement grandis un peu. Je n'ai pas la science infuse, mais aux regards de tes posts et au regard de tes signatures je me dis que tu n'as encore pas compris qu'on était sur un forum professionnel.

Si ce que je dis plus haut te semble être du chinois, je te conseille vivement de changer de métier ou d'entamer une formation... :merci:

--
Cordialement,

Philippe SAINT-BERTIN
Registered member
1,623 messages
Popularité : +100 (114 votes)
Posted on February, 18 2019 - 4:04 PM
Du coup, ca fait longtemps que je n'ai pas utilisé les triggers, je ne sais pas si c'est possible mais peut etre ceci pourrait marcher ? :

_Fichier est un Enregistrement de MonFichier
FichierVersMémoire(_Fichier ,MonFichier) // ON stock une copie de l'enregistrement dans la variable _Fichier
HLitRecherchePremier(MonFichier,IDMonFichier,_Fichier.IDMonFichier)
bDifferent est un booléen = Faux
SI HTrouve(MonFichier) ALORS
sListeRubrique est une chaîne = HListeRubrique(MonFichier)
POUR TOUTE chaîne sUneRubrique de sListeRubrique SEPAREE PAR RC // On compare dynamiquement chaque rubrique par indirection
SI {"MonFichier."+sUneRubrique} <> {"_Fichier."+sUneRubrique} ALORS
bDifferent = Vrai
SORTIR
FIN
FIN
SI bDifferent ALORS
Info("Ils sont differents")
MémoireVersFichier(_Fichier,MonFichier)
HModifie(MonFichier)
FIN
FIN
Registered member
948 messages
Popularité : +30 (92 votes)
Posted on February, 19 2019 - 1:37 PM
Coucou,

Sachant que la problématique précise :
Les rubriques reçues peuvent êtres des mémos binaires

@Simon :
HLitRechercheDernier(gsdContacts,IDContacts,Contacts.IDContacts)
E1 est un Enregistrement de Contacts=Contacts
E2 est un Enregistrement de Contacts=gsdContacts
SI E1..Contenu=E2..Contenu ALORS H.AFaire="A"
// La solution d'une clé hash dans, a voir si le temps de calcule de la clé et plus
// ou moins performant que la lecture de l'enregistrement.

Enregistrement..Contenu // ne récupère pas les rubriques de type mémo binaire

Tu ne vérifie donc à aucun moment si tes mémos binaires sont différent .

Type de variable : Enregistrement




Reference: https://doc.pcsoft.fr/?1000020962&verdisp=170

HRécupèreEnregistrement




Reference: https://doc.pcsoft.fr/?3044127&name=hrecupereenregistrement_fonction

---
In üs we trust - #92i - #LaPiraterieNestJamaisFinie - #PGP
Message modified, February, 19 2019 - 1:37 PM
Registered member
8 messages
Posted on February, 19 2019 - 5:43 PM
Charly CANDO a écrit :

Coucou,

Sachant que la problématique précise :
Les rubriques reçues peuvent êtres des mémos binaires


Merci pour l'info j'avais pas vu !