Précédent   Forum des professionnels en informatique > Bases de données > Autres SGBD > InterBase
InterBase Forum d'entraide sur le SGBD InterBase de Codegear. Avant de poster -> F.A.Q Interbase, Tutoriels
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 25/02/2005, 20h36   #1
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
Par défaut [IB6] Pb de "flush" buffer ?

J'écris en rafale une poignée de ligne par :
Code :
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 :
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
qi130 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2005, 23h21   #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
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)?
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2005, 00h13   #3
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
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 :
Citation:
la constante TPB() est inconnue
Code :
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 :
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
qi130 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2005, 00h20   #4
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
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
qi130 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2005, 11h55   #5
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
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 :
Citation:
la constante TPB() est inconnue
Code :
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 :
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 :
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 :
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 :
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 :
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 :
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 :
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.
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2005, 17h13   #6
Expert Confirmé Sénior
 
Avatar de qi130
 
Homme Pierre
Ingénieur qualité méthodes
Inscription : mars 2003
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Âge : 51
Localisation : France

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Finance

Informations forums :
Inscription : mars 2003
Messages : 3 726
Points : 4 739
Points : 4 739
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
qi130 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 13h08.


 
 
 
 
Partenaires

Hébergement Web