IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

InterBase Discussion :

[IB6] Pb de "flush" buffer ?


Sujet :

InterBase

  1. #1
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 903
    Points : 6 027
    Points
    6 027
    Par défaut [IB6] Pb de "flush" buffer ?
    J'écris en rafale une poignée de ligne par :
    Code : 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
         IBQuery1.SQL.Text:='INSERT INTO AFFECTATION ( AFF_ANNEE, ATE_REF, OUV_NUMSS ) '+
                            ' VALUES ('+Edit1.Text+', '+
                            QuoteOrNull(ComboBox1.Text)+', :numss)';
         for i:=1 to DstList.Items.Count do
            With IBQuery1 do begin
               ParamByName('numss').AsString:=SubWord(DstList.Items[i-1],1);
               try ExecSQL;
                except
                   on E:EDatabaseError do begin
                      IBCode:=IntToStr(SQLCode);
                      CATErreur('Erreur de mise à jour: '+E.Message+'-'+IBCode);
                      RollBack;
                      Exit;
                   end;
               end;
            end; // with
         Commit;
    La transaction est en nowait / concurrency

    De suite après, je tente de vérifier l'existence de ce que je viens d'écrire par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         IBQuery1.SQL.Clear;
         IBQuery1.SQL.Text:='SELECT COUNT(*) FROM AFFECTATION WHERE AFF_ANNEE=:aa '+
                              ' AND ATE_REF='+QuoteOrNull(ComboBox1.Items[ComboBox1.ItemIndex]);
         IBQuery1.ParamByName('aa').AsInteger:=StrtoInt(Edit1.Text);
         IBQuery1.Active:=True;
         if (IBQuery1.RecordCount>0) then
            if IBQuery1.Fields[0].AsInteger>0 then begin
    ......
    Je suis là en Read / consistency, et je ne retrouve pas mes petits.....(coté serveur, IBExpert me confirme leur présence)

    Par contre, en sortant/relançant mon prog, je les trouve

    J'ai du louper quelque chose, mais je ne vois pas quoi.

    Qui peut me sortir de cette ornière ?
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  2. #2
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut Re: [IB6] Pb de "flush" buffer ?
    Je suis là en Read / consistency, et je ne retrouve pas mes petits.....

    (coté serveur, IBExpert me confirme leur présence)[/quote]
    Ce qui prouve bien que c'est pas une question de flush de buffer...
    C'est votre deuxième transaction qui ne les voient pas.

    A quel moment a t elle débutée ?

    Pourquoi ne pas utiliser une simple ReadCommited (read_committed, rec_version, nowait)?

  3. #3
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 903
    Points : 6 027
    Points
    6 027
    Par défaut Re: [IB6] Pb de "flush" buffer ?
    Citation Envoyé par Barbibulle
    A quel moment a t elle débutée ?
    Je ne dis pas qu'elle débute...(pas de start) mais je repositionne la transaction ayant servi à l'écritute en read...

    Citation Envoyé par Barbibulle
    Pourquoi ne pas utiliser une simple ReadCommited (read_committed, rec_version, nowait)?
    Parceque je (me) suis mal documenté

    Bon, ma transaction servant à la lecture vient d'hériter des paramètres prescrits...

    Mais, ça "pète" ailleurs maintenant et en amont :
    la constante TPB() est inconnue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CustomerData.IBDatabase1.Connected:=False;
         CustomerData.IBDatabase1.Params.Clear;
          CustomerData.IBDatabase1.Databasename:=AdresseIP+':'+NomBase;
         CustomerData.IBDatabase1.Params.Add('lc_ctype=ISO8859_1');
         CustomerData.IBDatabase1.Params.Add('user_name='+Compte);
         CustomerData.IBDatabase1.Params.Add('password='+passW);
         Prepare2Read;
     
         with BtnBottomDlg4 do begin
           IBQuery1.Database:=CustomerData.IBDatabase1;
           IBQuery1.Transaction:=CustomerData.IBTransaction1;
           IBQuery1.SQL.Clear;
           IBQuery1.SQL.Text:='select HABIL FROM VERIF_PSW ('+QuotedStr(Compte)+')';
           With IBQuery1 do begin
             try Active:=True;
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Procedure Prepare2Read;
    begin
         with CustomerData do begin
            IBDatabase1.DefaultTransaction:=IBTransaction1;
            IBTransaction1.Params.Add('read_commited');
            IBTransaction1.Params.Add('rec_version');
            IBTransaction1.Params.Add('nowait');
            IBTransaction1.DefaultDatabase:=IBDatabase1;
         end;
    end;
    Alors que ça marche impec en read/consistency !

    J'ai poussé + loin: le code ci-dessus bénéficie d'un paramétrage manuelle de la transaction (read/consistency), je laisse l'appel à Prepare2Read pour relire mes inserts (cf le 1er post), mais ces insert sont toujours invisibles
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  4. #4
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 903
    Points : 6 027
    Points
    6 027
    Par défaut
    Quel je fais: j'utilise une transaction non initialisée: je l'ai dropé sur la forme et puis rien !!!!!

    Bref je ferme tout pour ce soir !

    Mais si qq'un a un tuyau sur ce TPB......
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  5. #5
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut Re: [IB6] Pb de "flush" buffer ?
    Citation Envoyé par qi130
    Citation Envoyé par Barbibulle
    A quel moment a t elle débutée ?
    Je ne dis pas qu'elle débute...(pas de start) mais je repositionne la transaction ayant servi à l'écritute en read...
    Elle débute automatiquement dès la première utilisation. Et se termine automatiquement dès que tous les Dataset qui lui sont attachés sont fermés (avec un commit par defaut). Ou mannuellement avec un Commit ou Rollback.

    Citation Envoyé par qi130
    Citation Envoyé par Barbibulle
    Pourquoi ne pas utiliser une simple ReadCommited (read_committed, rec_version, nowait)?
    Parceque je (me) suis mal documenté

    Bon, ma transaction servant à la lecture vient d'hériter des paramètres prescrits...

    Mais, ça "pète" ailleurs maintenant et en amont :
    la constante TPB() est inconnue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CustomerData.IBDatabase1.Connected:=False;
         CustomerData.IBDatabase1.Params.Clear;
          CustomerData.IBDatabase1.Databasename:=AdresseIP+':'+NomBase;
         CustomerData.IBDatabase1.Params.Add('lc_ctype=ISO8859_1');
         CustomerData.IBDatabase1.Params.Add('user_name='+Compte);
         CustomerData.IBDatabase1.Params.Add('password='+passW);
         Prepare2Read;
     
         with BtnBottomDlg4 do begin
           IBQuery1.Database:=CustomerData.IBDatabase1;
           IBQuery1.Transaction:=CustomerData.IBTransaction1;
           IBQuery1.SQL.Clear;
           IBQuery1.SQL.Text:='select HABIL FROM VERIF_PSW ('+QuotedStr(Compte)+')';
           With IBQuery1 do begin
             try Active:=True;
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Procedure Prepare2Read;
    begin
         with CustomerData do begin
            IBDatabase1.DefaultTransaction:=IBTransaction1;
            IBTransaction1.Params.Add('read_commited');
            IBTransaction1.Params.Add('rec_version');
            IBTransaction1.Params.Add('nowait');
            IBTransaction1.DefaultDatabase:=IBDatabase1;
         end;
    end;
    Alors que ça marche impec en read/consistency !

    J'ai poussé + loin: le code ci-dessus bénéficie d'un paramétrage manuelle de la transaction (read/consistency), je laisse l'appel à Prepare2Read pour relire mes inserts (cf le 1er post), mais ces insert sont toujours invisibles
    Pourquoi faites vous ça comme ça ?

    Le plus simple est de poser sur votre DataModule, un TIBDataBase vous double cliquez dessus pour le paramétrer. Ensuite un TIBTransaction, vous affectez au IBDatabase.DefaultTransaction la référence au composant transaction et dans le IBTransaction.DefaultDatabase la database. Ces deux affectations permettent d'avoir une transaction par défaut pour cette base, mais on n'est pas obligé de l'utiliser. (Je vais expliquer après). Double cliquez sur le TIBTransaction et cochez ReadCommited.

    Visiblement vous avez un PS pour vérifier dès la connexion une habilitation. Placer un TIBStoredProc renseignez le DataBase et choisissez dans la liste proposé dans StoredProcName la PS VERIF_PSW.
    Dans l'évènement AfterConnect du TIBDadabase codez ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IBStoredProc.ParamByName('NomDuParametreDeLaPS').AsString := Compte;
    // Oubien IBStoredProc.Params[0].AsString := Compte;
    IBStoredProc.ExecProc;
    MaVariable := IBStoredProc.ParamByName('HABIL').AsLeBonType;
    Ensuite pour vos deux query:

    Code : 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
    IBQuery1.SQL.Text:='INSERT INTO AFFECTATION ( AFF_ANNEE, ATE_REF, OUV_NUMSS ) '+ 
                            ' VALUES ('+Edit1.Text+', '+ 
                            QuoteOrNull(ComboBox1.Text)+', :numss)'; 
         for i:=1 to DstList.Items.Count do 
            With IBQuery1 do begin 
               ParamByName('numss').AsString:=SubWord(DstList.Items[i-1],1); 
               try ExecSQL; 
                except 
                   on E:EDatabaseError do begin 
                      IBCode:=IntToStr(SQLCode); 
                      CATErreur('Erreur de mise à jour: '+E.Message+'-'+IBCode); 
                      RollBack; 
                      Exit; 
                   end; 
               end; 
            end; // with 
         Commit;
    Pourquoi mixer deux mannières de d'exécuter une requetes ? Soit vous faites une requetes paramétré soit une requete dynamique, c'est plus simple il me semble.
    En conception le poserai donc un TIBQuery que je nommerai IBQInsertAffectation, Clique droit "Modifier SQL" puis je mettrai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO AFFECTATION ( AFF_ANNEE, ATE_REF, OUV_NUMSS )
           VALUES (:AFF_ANNEE, :ATE_REF, :NUMSS);
    Posez un TIBTransaction que vous nommerez IBTInsertAffectation, doubleCliquez dessus et mettez ReadCommited par exemple. Dans le IBQInsertAffectation.Transaction choisissez le IBTInsertAffectation

    Puis quand j'ai besoins de l'utiliser :

    Code : 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
     
    With IBQInsertAffectation do begin 
      ParamByName('AFF_ANNEE').AsString := Edit1.Text;
      ParamByName('ATE_REF').AsString := ComboBox1.Text;
      for i:=1 to DstList.Items.Count do begin
        ParamByName('numss').AsString:=SubWord(DstList.Items[i-1],1); 
        try ExecSQL; // La transaction est automatiquement ouverte lors du 1er ExecSQL
        except 
          on E:EDatabaseError do begin 
            IBCode:=IntToStr(SQLCode); 
            CATErreur('Erreur de mise à jour: '+E.Message+'-'+IBCode); 
            RollBack; 
            Exit; 
          end; // End Except DataBaseError
        end; // End try
      end;  //End For
    end; // with 
    Commit;
    Ensuite dans un autre TIBQuery IBQCompteAffectation :
    Clique droit "Modifier SQL" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(*) as NbAffectation FROM AFFECTATION WHERE AFF_ANNEE=:aa AND ATE_REF=:REF;
    Il n'est pas utile d'affecter une transaction particulière, celle par défaut de la database convient tout a fait, vu qu'on veux lire uniquement les résultats validés.
    Clique droit sur IBQCompteAffectation puis "Editeur de champs" (ou double clique)
    Dans la petite fenêtre qui s'ouvre faites un clique droit Ajouter tous les champs (ou CTRL + F). Normalement un champ appelé NbAffectation apparait.

    Lorque vous voulez l'exécuter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    With IBQCompteAffectation
      Close; // Au cas où elle aurait été ouverte (mode conception ou par du code qui ne l'aurait pas fermée
      ParamByName('aa').AsString :=Edit1.Text;
      ParamByName('REF').AsString := ComboBox1.Items[ComboBox1.ItemIndex];
      Open;
    end; // End With
    // La requete étant un count(*) il y aura forcément un résultat donc il est innutile de tester le recordCount (d'ailleur il est préférable de tester le EOF)
     
    if IBQCompteAffectationNbAffectation.AsInteger > 0 then begin
    ...
    Voilà comment procéder.

  6. #6
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 903
    Points : 6 027
    Points
    6 027
    Par défaut
    Merci Barbibulle pour toutes ces précieuses informations que je vais m'attacher à mettre en pratique.

    Je dois confesser que ma seule expérience de programmation avec un SGBD relationnel commence à dater et est réduite à du COBOL/CICS/DB2...

    DB2 pour lequel toutes les finesses (finasseries?) offertes par IB (et d'autres) n'existent pas (du moins pour le programmeur lambda).

    Sans parler que la doc sur ce sujet n'est pas très répandue

    D'autre part, ce qui m'occupe actuellement (et qui m'amène souvent sur ce forum) est le portage sous IB d'un soft qui utilisait MyLittlebase...

    Bref, que des difficultés en perspective...mais je sais où m'adresser en cas de problème

    Mais, j'avance quand même.

    Merci encore
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo