Avatar billede kroning Nybegynder
14. oktober 2008 - 13:26 Der er 17 kommentarer og
1 løsning

Ændre read-only felt i TClientDataSet

Jeg henter data fra MySQL ind i en ADOQuery og derefter overfører jeg resultatet til en TClientDataSet således vha. en TDataSetProvider:

ClientDataSet.ProviderName:='DataSetProvider';
ClientDataSet.Open;
ClientDataSet.ProviderName:='';

Mit problem nu er at jeg har et autoinc felt i min MySQL tabel (IDKode), dette felt kan jeg ikke få lov til at ændre i når jeg kalder Edit, altså:

ClientDataSet.Edit;
ClientDataSet.FieldByName('IDKode').AsInteger:=7364;
ClientDataSet.Post; //fejler her med cant modify a read-only field

Ved Insert er der ingen problemer:
ClientDataSet.Fields.FieldByName('IDKode').ReadOnly:=false;
ClientDataSet.Insert;
ClientDataSet.FieldByName('IDKode').AsInteger:=7364;
ClientDataSet.Post;

At sætte FieldByName('IDKode').ReadOnly:=false; før en Edit har ingen virkning.
Avatar billede martinlind Nybegynder
14. oktober 2008 - 13:30 #1
Har du ikke nogle fielddefs på dit clientdataset du skal ind og rette i, det må være det der er problemet, read-only flaget er vel ført med over i dit clientdataset's fielddefs....
Avatar billede kroning Nybegynder
14. oktober 2008 - 13:34 #2
Jeg har prøvet at rette på alle de fielddefs for IDKode jeg syntes jeg kan finde som kunne have noget med det at gøre uden held.
Det mærkelige er at det jo virker fint med at sætte ReadOnly:=false; før en Insert.
Avatar billede martinlind Nybegynder
14. oktober 2008 - 13:46 #3
Ja men jeg tror først "valideringen" kommer i post. en løsning kunne måske være at oprettte dine fielddefs selv i dit cds inden du overfører data..
Avatar billede kroning Nybegynder
14. oktober 2008 - 14:02 #4
Min cds bliver "nulstillet" når jeg kører denne kode:
ClientDataSet.ProviderName:='DataSetProvider';
ClientDataSet.Open;
ClientDataSet.ProviderName:='';

så alle fields jeg evt. har oprettet inden er væk.
Avatar billede kroning Nybegynder
14. oktober 2008 - 14:03 #5
Men som nævnt så virker post jo også fint i en Insert, det er kun ved Edit det fejler.
Avatar billede martinlind Nybegynder
14. oktober 2008 - 14:20 #6
Ja men på din mysql db er det et autoinc field og sikkert også primarykey osv. og det gør sikkert at den ikke vil lave en edit.... men du har da ret det er lidt mærkeligt at du ikke også får en fejl ved insert
Avatar billede kroning Nybegynder
14. oktober 2008 - 14:32 #7
Men efter jeg har sat ClientDataSet.ProviderName:=''; så er forbindelsen til MySQL afbrudt og så burde det da være muligt at ændre på alle felter.
Avatar billede martinlind Nybegynder
14. oktober 2008 - 16:05 #8
ja men den har jo nok "læst" nogle metadata og husket dem, somewhere.....
Avatar billede hrc Mester
14. oktober 2008 - 21:32 #9
Jeg læste et indslag om hvordan man taklede de auto-inc felter - og hvordan man håndterede dem når andre client-dataset refererede til dem. Skrev det også ud og skal klistre linket ind i morgen når jeg møder. Humlen i det var at man undlod at hente nøglen (medmindre man skal bruge den) og lavede et heltalsfelt som pseudonøgle. Indtil man applyer rettes de til de rigtige værdier. Altså ikke en nem og strømlinet løsning, men et paradigme på den problemstilling (første gang jeg bruger ordet paradigme, fedt).
Avatar billede kroning Nybegynder
14. oktober 2008 - 22:07 #10
Jeg har midlertidig ordnet problemet ved at flytte alle poster fra ADO til ClientDataSet manuelt, det er en langsommere løsning men så længe det ikke drejer sig om flere tusinde poster er der ingen problemer.

Det gør jeg således:
DataSet er min TClientDataSet

  DataForm.ADOQuery.Open;

    for i:=0 to DataForm.ADOQuery.FieldCount-1 do
    with DataSet.FieldDefs.AddFieldDef do
  begin
      DataType:=DataForm.ADOQuery.FieldDefs[i].DataType;
    if DataType=ftAutoInc    then
      DataType:=ftInteger;
    Name:=DataForm.ADOQuery.FieldDefs[i].Name;
    Size:=DataForm.ADOQuery.FieldDefs[i].Size;
  end;

  DataSet.CreateDataSet;

  while not DataForm.ADOQuery.Eof do
  begin
      DataSet.Append;
      for i:=0 to DataSet.FieldCount-1 do
            DataSet.FieldByName(DataSet.FieldDefs[i].Name).Value:=DataForm.ADOQuery.Fields[i].Value;
      DataSet.Post;
        DataForm.ADOQuery.Next;
  end;
  DataForm.ADOQuery.Close;
  DataSet.First;
Avatar billede hrc Mester
15. oktober 2008 - 13:39 #11
Det er også i retning af hvad eksemplet, jeg læste om, gjorde. Linket jeg kiggede i er: http://dn.codegear.com/article/20847
Avatar billede kroning Nybegynder
15. oktober 2008 - 13:56 #12
hrc> Men den forklarer ikke hvorfor jeg kan sætte ReadOnly=false for mit autoinc felt i en Insert og ændre feltet uden problemer.

Men hvis jeg sætter ReadOnly=false for mit autoinc felt i en Edit så får jeg en fejl. (Trying to modify read-only field)
Avatar billede hrc Mester
15. oktober 2008 - 14:08 #13
Men, undskyld mig, så er det vel fordi et autoinc-felt ... netop er readonly, ikke? Jeg tror du gør det på den rigtige måde med manuelt at kopiere felterne. Man kan desværre ikke, vha. "alter table", ændre feltet til et dødeligt int-felt.
Avatar billede kroning Nybegynder
15. oktober 2008 - 16:37 #14
Da jeg brugte dbExpress var der ingen problemer og jeg syntes jo at når man afbryder forbindelsen til MySQL ved at sætte ClientDataSet.ProviderName:=''; så burde man også have lov til at ændre som man har lyst.
Avatar billede kroning Nybegynder
15. oktober 2008 - 16:38 #15
Jeg venter lige nogle dage hvis en skulle have løsningen, men ellers smid nogle svar.
Avatar billede kroning Nybegynder
06. november 2008 - 18:20 #16
Nogen der vil have points?
Avatar billede martinlind Nybegynder
06. november 2008 - 18:41 #17
Fik du løst noget ?
Avatar billede kroning Nybegynder
06. november 2008 - 19:31 #18
Næ, jeg gør som jeg beskrev kl. 22:07:03 og det virker ganske fint.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester