23. oktober 2002 - 08:33Der er
16 kommentarer og 1 løsning
ClientDataSet - dbExpress
Jeg har en databaseapplikation hvor en del af interfacet er oprettet på følgende måde:
Brugerinterface ser på DB gennem følgende komponenter
1. SQLConnection1 forbundet til databasen 2. SQLDataset1 forbundet til d.o. 3. DataSetProvider forbundet til d.o. 4. ClientDataSet forbundet til d.o. 5. alm. dataset forbundet til d.o.
Brugeren har mulighed for at ændreværdier i en tabel gennem diverse dbEdit komponeter på en dialog, når der trykkes o.k. på denne dialog afvikles følgende kode:
procedure TdlgInt.OKBtnClick(Sender: TObject); begin try DM.cdsInt.ApplyUpdates(-1); except ShowMessage('Error in data please retype !'); DM.cdsInt.CancelUpdates; end; end;
Ofte giver det fejlen: Record not found or change by another user
Det er et dataopsamlingsprogram og der foregår konstant en hel del læsninger/skrivninger af andre data i db'en, igennem TSQLdataset samt TSQLQuerys, disse er alle forbundet til db'en gennem en anden connection, SQLConnection2
Så virker det ekstra mystisk da MySQL ikke plejer at tage sig af om nogen bruger den record du er ved at opdatere.. Så vidt jeg ved kender MySQL ikke til transactions og locking..
Ifølge online kilder opstår dette problem hyppigt ved databaser der benytter timestamps og datetime felter, specielt hvis de er indexed. Det skyldes en bug i dbExpress-komponenterne.. Jeg vil da lige poste noget jeg fandt, i tilfælde af at det kan bruges i din situation. :)
To solve this, use a primary key/index and the UpdateMode = upWhereKeyOnly mode with keys on fields that are not timestamp/datetime/etc (do not make the timestamp values indexed). This will avoid VCL to generate a wrong WHERE statement. If in your database these fields are indexed, removing the pfInWhere option from the TField.ProviderFlags property for that filed should be enough. If the actual value in your table that have no fraction or timezone value values, the generated SQL will be able to find that record (because it will use only the indexed fields in the WHERE clause) and the update will suceed.
angelod> Det plejer jeg normalt også, men så bruger jeg normale editfelter som jeg så sender til db'en via et sql statement, syntes bare lige jeg ville prøve om ikke det kunne lykkeds med de "officielle" dataware komponenter
angelod> Hvis jeg stopper den øvrige kommunikation til databasen som kører igennem connection2 (altså dataopsamlingsdelen) virker det uden problemer, og jeg må indrømme at det er betydeligt mere elgant end at skrive sine sqlstatemensts selv, jeg plejer normalt at have 3 forskellige "procedure" til det samme et insert, et update (edit) og et delete statemenst som så får sine værdier fra alm. edit felter, og sqlstatementsne samt det kode som skal til at parse til felterne bliver ret lange når man har en 20-25 felter og udfylde
Je' ve' de' gåt' :D Men jeg er først og fremmest PHP programmør, og der skriver jeg selv mine MySQL statements, så det er blevet en vane. Prøver dog at vænne mig til at bruge komponenterne bedre i Delphi. :P
slukker og lukker.......har desværre ikke en løsning
Synes godt om
Ny brugerNybegynder
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.