Précédent   Forum des professionnels en informatique > Bases de données > Firebird > Débuter
Débuter Forum d'entraide pour débuter avec Firebird
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/01/2005, 08h16   #1
Invité de passage
 
Inscription : janvier 2005
Messages : 3
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 3
Points : 2
Points : 2
Par défaut Triggers et Procédures stockées

Bonjour,

Je débute avec Interbase et j'ai encore du mal avec les triggers et procédures stockées qui me paraissent pourtant bien intéressants, certains traitements ayant effectivement mieux leur place sur le serveur qu'au sein des applis. Existe-t-il un bon tuto sur le sujet ? j'ai trouvé pas mal de choses, mais rien de vraiment complet, notemment au niveau du langage à utiliser et de sa syntaxe...

J'ai un cas concret à mettre en oeuvre, et si quelqu'un pouvait m'aider, ce serait sympa. Voilà : j'ai une table (moins d'une centaine d'enregistrements) laquelle doit être ordonnée selon un critère défini par l'utilisateur et que ce dernier doit pouvoir changer à tout instant. J'ai donc créé pour cette table un champ "NumeroDordre", qui définit un index sur ma table. C'est à l'utilisateur de donner les numéros d'ordre de façon à obtenir le classement qu'il souhaite. Jusque là, rien que de très simple et logique.

Je voudrais maintenant que dès qu'un utilisateur modifie le numéro d'ordre d'un enregistrement, au moment de la validation de ses modifications, toute la table soit balayée pour remettre en ordre (c'est le cas de le dire !) les numéros d'ordre. Pour être clair, disons que je voudrais obtenir dans ma table ce qui est réalisé sous Delphi avec les propriétés "Tab Order" des composants d'une fiche : dès qu'on en change un, tous sont reclassés.

Je pense qu'un tel traitement a tout à fait sa place sur le serveur, mais doit-je pour cela faire un trigger ou une procédure stockée ? Et comment l'écrire ? Il faudrait quelque chose du style :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
NO=Ancien numéro d'ordre de l'enregistrement modifié
NN=Nouveau numéro d'ordre de l'enregistrement modifié
IF NO<NN
   begin
      Trouver l'enregistrement NO+1
         do
            begin
                Décrémenter Numéro d'ordre
                Next
            end
         while Numéro d'ordre <= NN
   end
else
   begin
       Trouver l'enregistrement NN-1
        Do
            begin
                Incrémenter Numéro d'ordre
                Previous
            end
         while Numéro d'ordre >= NO
   end
... Mais je ne sais pas l'écrire dans le langage (SQL ?) des procédures stockées...
Merci à ceux qui pourront m'aider !
agecanonix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2005, 10h59   #2
Membre Expert
 
Avatar de Barbibulle
 
Frédéric
Inscription : octobre 2002
Messages : 1 722
Détails du profil
Informations personnelles :
Nom : Frédéric
Âge : 42

Informations forums :
Inscription : octobre 2002
Messages : 1 722
Points : 2 025
Points : 2 025
Je pense que ce type de traitement sera bien mieux sur le client (Delphi).

Car sous Delphi vous pouvez updater la numérotation dans la base une fois qu'il a ordonné comme il le souhaite tous vos enregistrements (donc maximum un update/enregistrement (une centaine max).

Si vous le faites faire par le serveur et donc à chaque changement vous risquez de faire plein d'update pour rien.

Mettons que votre utilisateur prenne le dernier enregistrement pour le mettre en 1er vous allez updatez toute votre table (100 updates) puis il prend encore le dernier pour le mettre en 1er de nouveau vous updatez toute votre table (100 updates ce qui fait 200 Updates pour ces deux changements) etc etc. C'est évidemment le cas extreme mais c'est pour montrer que si vous faites ce traitement sur le client et que vous n'updatiez qu'un fois qu'il a bien ordonné ses enregistrements vous aurez 100 updates max (si vous gèrez un flag pour indiquer ceux dont l'ordre n'a pas changé vous en aurez moins).

Sinon bien entendu on peut numéroter avec une PS ou un trigger.

Si votre numéro d'ordre n'est pas un index unique ou la cle primaire et que ce chiffre est >=0 alors vous pouvez faire :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SET Term ^;
 
CREATE PROCEDURE Renumerote(AncienOrdre integer, NouveauOrdre integer)
AS
BEGIN
  UPDATE MaTable SET NumOrdre=-1 WHERE  NumOrdre=:AncienOrdre;
 
  IF (AncienOrdre > NouveauOrdre) then
    UPDATE MaTable SET NumOrdre=NumOrdre+1 WHERE 
      NumOrdre BETWEEN :NouveauOrdre AND (:AncienOrdre -1);
 
  IF (AncienOrdre < NouveauOrdre) then
    UPDATE MaTable SET NumOrdre=NumOrdre-1 WHERE 
      NumOrdre BETWEEN (:AncienOrdre +1 )  AND :NouveauOrdre;
 
  UPDATE MaTable SET NumOrdre=:NouveauOrdre WHERE  NumOrdre=-1;
END^
 
SET Term ;^
Je n'ai pas testé mais je dois pas être loin.
Si c'est un index unique ou une clé primaire il faudra procéder autrement (avec des For select ...)

Mais bon à mon sens une gestion en locale (en mémoire) puis les updates necessaires en fin de traitement seraient mieux il me semble.
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2005, 11h33   #3
Membre du Club
 
Avatar de jibe74
 
Inscription : avril 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 121
Points : 48
Points : 48
Salut,

Intéressant, ton truc, agecanonix ! Et marrant : figure-toi que j'avais eu quelque chose d'étrangement similaire à résoudre il y a quelques années. Mais bon, mon expérience ne te servira malheureusement pas à grand chose, le contexte était très différent (simple fichier indexé et non SGBD...)

Je pense que Barbibulle a totalement répondu à ta question. J'ajouterais simplement une petite nuance : dans mon cas, j'aurais opté pour un trigger. Non que les arguments de Barbibulle ne soient pas valables, au contraire, mais ils s'appliquent plutôt dans le cas où tu as des mises à jour en série (tous ou plusieurs enregistrements vont changer de numéro d'ordre). Dans mon cas, il n'y en avait généralement qu'un qui était modifié. Et à ce moment-là, un traitement par trigger sur le serveur me parait non seulement mieux placé mais aussi plus simple à mettre en oeuvre.

Je profite de ton post pour poser une question à Barbibulle (et aux autres aussi, bien sûr !) sur un sujet qui me tracasse (j'en ai parlé dans ce topic) et pour lequel tu seras peut-être aussi heureux d'avoir une réponse : quid des accès concurrentiels dans un cas comme dans l'autre (trigger ou traitement local) ? Comment bien les gérer ? Ce cas, qui met en jeu simultanément plusieurs enregistrements (voire tous) d'une table est un exemple intéressant !
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein.
jibe74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2005, 10h16   #4
Invité de passage
 
Inscription : janvier 2005
Messages : 3
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 3
Points : 2
Points : 2
Bonjour,

Merci pour vos réponses !

Finalement, j'ai suivi les conseils de Barbibulle. Le cas de jibe74 est un cas particulier, je préfère avoir une solution plus générale.

Mais j'essaierai quand même la procédure de Barbibulle, à l'occasion, pour me faire la main avec cette technique
agecanonix est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h16.


 
 
 
 
Partenaires

Hébergement Web