4D v14.3Présentation des triggers |
||
|
4D v14.3
Présentation des triggers
Présentation des triggers
Un trigger est une méthode associée à une table. C'est une propriété d'une table. Vous n'appelez pas un trigger, les triggers sont appelés automatiquement par le moteur de 4D à chaque fois qu'un enregistrement de la table est manipulé (ajout, suppression et modification). Les triggers sont des méthodes qui peuvent éviter des opérations “illégales” dans votre base. Par exemple, dans une facturation, vous pouvez empêcher qu'un utilisateur crée une facture sans spécifier à qui elle doit être adressée. Les triggers sont un outil puissant permettant de contrôler les opérations sur les tables, et d'éviter des pertes de données accidentelles. Vous pouvez créer des triggers très simples et les rendre de plus en plus sophistiqués. Par défaut, lorsque vous créez une table en mode Développement, la table n'a pas de trigger. Pour utiliser un trigger pour une table, vous devez :
Activer un trigger qui n'est pas encore écrit ou écrire un trigger sans l'activer n'affecte pas les opérations effectuées sur une table. Pour activer le trigger, sélectionnez les options Triggers pour la table dans la fenêtre de l'Inspecteur de structure : Voici la description de ces options : Si cette option est sélectionnée, le trigger sera appelé à chaque fois qu'un enregistrement de la table est modifié, c'est-à-dire dans les circonstances suivantes :
[latable]lechamp:=[latable]lechamp Si cette option est sélectionnée, le trigger sera appelé à chaque fois qu'un enregistrement de la table est supprimé, c'est-à-dire dans les circonstances suivantes :
Note : La commande VIDER TABLE ne provoque PAS l'appel du trigger. Si cette option est sélectionnée, le trigger sera appelé à chaque fois qu'un enregistrement est créé dans la table, c'est-à-dire dans les circonstances suivantes :
Pour créer un trigger pour une table, utilisez la fenêtre de l'Explorateur, cliquez sur le bouton Editer dans la palette de l'Inspecteur de structure ou double-cliquez sur le titre de la table dans la fenêtre de Structure en appuyant sur la touche Alt (sous Windows) ou Option (sous Mac OS). Pour plus d'informations, reportez-vous au manuel Mode Développement. Un trigger peut être invoqué pour l'un des trois événements moteur décrits ci-dessus. Dans le trigger, vous détectez quel événement a lieu en appelant la fonction Evenement trigger. Cette fonction retourne une valeur numérique qui indique l'événement moteur. Typiquement, vous écrivez un trigger avec une structure du type "Au cas ou" sur le résultat retourné par Evenement trigger : // Trigger pour [UneTable] Un trigger a deux finalités :
A chaque fois qu'un enregistrement est sauvegardé (ajouté ou modifié) dans une table [Documents], vous souhaitez “estampiller ” l'enregistrement avec des marqueurs de création et de modification. Vous pouvez écrire le trigger suivant : // Trigger pour table [Documents] Note : La fonction Time stamp utilisée dans cet exemple est une petite méthode projet retournant le nombre de secondes écoulées depuis une date choisie arbitrairement. Une fois que ce trigger a été écrit et activé, peu importe la façon dont vous ajoutez ou modifiez un enregistrement dans la table [Documents] (saisie de données, import, méthode projet, plug-in 4D), la valeur des deux champs [Documents]Creation Stamp et [Documents]Modification Stamp sera automatiquement affectée par le trigger avant que l'enregistrement ne soit écrit sur disque. Note : Voir l'exemple de la commande PROPRIETES DOCUMENT pour une analyse complète de cet exemple. Pour accepter ou rejeter une opération de la base, le trigger doit retourner un code d'erreur de trigger dans le résultat de la fonction $0. Prenons le cas d'une table [Employés]. Pendant la saisie de données, vous contrôlez le champ [Employés]No Séc.Soc. Par exemple, lorsque l'utilisateur clique sur le bouton de validation, vous vérifiez le champ utilisant la méthode objet du bouton : // Méthode objet bouton bAccept Si la valeur du champ est correcte, vous acceptez la saisie de données, sinon vous affichez une alerte et restez en saisie de données. Si vous créez aussi des enregistrements pour la table [Employés] par programmation, le code ci-dessous serait valide MAIS violerait la règle imposée dans la méthode objet créée plus haut : ` Extrait d'une méthode projet En utilisant un trigger pour la table [Employés], vous pouvez appliquer la contrainte sur [Employés]No Séc.Soc à tous les niveaux de la base. Le trigger serait du type : // Trigger pour [Employés] Une fois que ce trigger est écrit et activé, la ligne STOCKER ENREGISTREMENT([Employés]) de la méthode projet ci-dessus génèrera une erreur moteur -15050 et l'enregistrement ne sera PAS sauvegardé. De la même façon, si un plug-in 4D essayait de sauvegarder un enregistrement dans [Employés] avec un numéro de sécurité sociale incorrect, le trigger génèrerait la même erreur et l'enregistrement ne serait pas sauvegardé non plus. Le trigger garantit que personne (utilisateur, développeur, plug-in...) ne peut violer la règle sur le numéro de sécurité sociale (à dessein ou par erreur). Notez que même si vous n'avez pas créé de trigger pour une table, la base peut retourner des erreurs moteur lorsque vous essayez de sauvegarder ou de détruire un enregistrement. Vous pouvez, par exemple, recevoir l'erreur -9998, si vous essayez de sauvegarder un enregistrement. Les triggers retournent de nouveaux types d'erreurs dans 4D :
Important : Vous pouvez retourner le code d'erreur de votre choix. Cependant, n'utilisez pas des codes d'erreurs déjà utilisés par le moteur de 4D. Nous vous recommandons fortement d'utiliser des codes compris entre -32000 et -15000. Nous réservons les erreurs supérieures à -15000 au moteur de 4D. Au niveau du process, vous gérez les erreurs trigger de la même façon que les erreurs du moteur de base de données :
Notes :
Même si un trigger ne retourne pas d'erreur ($0:=0), cela ne signifie pas qu'une opération de la base s'effectuera correctement. Il peut y avoir eu un doublon sur l'index unique. Si l'opération est la mise à jour d'un enregistrement, ce dernier peut être verrouillé, une erreur d'entrée/sortie peut se produire, bien d'autres choses encore peuvent arriver. Ces vérifications sont effectuées après l'exécution du trigger. Cependant, du point de vue du plus haut niveau du process en exécution, les erreurs retournées par le moteur de la base de données ou celle d'un trigger sont de même nature : une erreur trigger est une erreur du moteur de la base de données. Les triggers sont exécutés au niveau du moteur de la base de données. Ce point est illustré dans le schéma suivant : Les triggers sont exécutés sur la machine où est situé le moteur de la base de données. Si ce point est une évidence dans le cas de 4D en local, il convient de rappeler que pour 4D Server, les triggers sont exécutés sur la machine serveur (dans le process "jumeau" du process ayant déclenché le trigger) et non sur la machine cliente. Quand un trigger est appelé, il s'exécute dans le contexte du process qui tente l'opération. Ci-dessous, ce process est appelé process appelant l'exécution du trigger.
Soyez prudent lorsque vous utilisez les autres objets de la base et du langage, car un trigger peut s'exécuter sur une machine différente de celle du process appelant : c'est le cas avec 4D Server !
Les transactions doivent être gérées au niveau du process appelant. Il est fortement déconseillé de gérer des transactions au niveau du trigger. Si, pendant l'exécution d'un trigger, vous devez ajouter, modifier ou détruire plusieurs enregistrements et souhaitez garantir l'intégrité de vos données à l'aide d'une transaction, vous devez d'abord tester (à partir du trigger) si le process appelant est en cours de transaction avec la commande Transaction en cours. En effet, si ce n'est pas le cas et si le trigger rencontre un enregistrement verrouillé, le process appelant n'aura aucun moyen d'annuler a posteriori les actions déjà effectuées par le trigger. Par conséquent, si vous n'êtes pas en transaction, ne commencez pas les opérations à exécuter, et retournez simplement une erreur dans $0 afin de signaler au process appelant que l'opération de base de données doit être exécutée dans une transaction. Note : Afin d'optimiser le fonctionnement combiné des triggers et des transactions, 4D n'appelle PAS les triggers lors d'un VALIDER TRANSACTION. Cela évite que les triggers soient exécutés deux fois. Prenons l'exemple de la structure suivante : Note : Les tables ont été contractées (il y a davantage de champs). Pour les nécessités de cette documentation, nous admettrons que la base “autorise” la suppression d'une facture. Voyons aussi comment une telle opération serait gérée au niveau du trigger (puisque vous pourriez aussi décider d'effectuer l'opération au niveau du process). Afin que soit maintenue l'intégrité relationnelle des données, la suppression d'une facture requiert les actions suivantes de la part du trigger de [Factures] :
Tout d'abord, le trigger de [Factures] ne doit effectuer ces actions que si le process appelant est en transaction, afin qu'une annulation rétroactive soit possible en cas de rencontre d'un enregistrement verrouillé. Deuxièmement, le trigger de [Lignes facture] est en cascade avec le trigger de [Factures]. Le premier s'exécute “à l'intérieur” du second parce que la destruction des éléments de la liste est consécutive à un appel à SUPPRIMER SELECTION dans le trigger de [Factures]. Ajoutons que toutes les tables dans cet exemple ont des triggers activés pour tous les événements de la base de données. La cascade des triggers sera :
Dans les triggers, vous pouvez détecter à quel niveau un trigger est exécuté grâce à la commande Niveau du trigger. De plus, vous pouvez aussi obtenir des informations sur les autres niveaux en utilisant la commande PROPRIETES DU TRIGGER. Si, par exemple, vous détruisiez un enregistrement [Produits] à un niveau process, le trigger de [Produits] s'exécuterait au niveau 1, non au niveau 3, comme plus haut. Avec Niveau du trigger et PROPRIETES DU TRIGGER, vous pouvez identifier la raison d'une action. Dans l'exemple ci-dessus, une facture est supprimée au niveau process. Prenons pour hypothèse que nous voulons détruire un enregistrement [Clients] au niveau process. Le trigger de [Clients] devrait alors être conçu pour détruire toutes les factures liées à ce client. Cela signifie que le trigger [Factures] devrait être invoqué comme plus haut, mais pour une autre raison. Du trigger [Factures], vous pouvez détecter si le niveau est 1 ou 2. S'il est 2, vous pouvez vérifier si oui ou non c'est à cause de la suppression de l'enregistrement Client lui-même. Si tel est le cas, vous n'avez même plus besoin de vous préoccuper de la mise à jour du champ Ventes. Quand vous manipulez l'événement moteur Sur sauvegarde nouvel enreg, vous pouvez appeler la commande Numerotation automatique pour maintenir un numéro d'identification unique pour chaque enregistrement d'une table. // Trigger pour la table [Factures] |
PROPRIÉTÉS
Produit : 4D VOIR AUSSI
Evenement trigger UTILISATION DE L'ARTICLE
4D - Langage ( 4D v14 R3) Hérité de : Présentation des triggers ( 4D v11 SQL Release 6) |