Page 1 of 3 1 2 3 LastLast
Results 1 to 15 of 43

Thread: autoincrement veld vullen via clientdataset

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747

    autoincrement veld vullen via clientdataset

    Ik moet een voorbeeldje maken met een TClientdataset, TMyQuery (Devart) en TDatasetProvider. Er zijn nogal problemen met MySQL 5.1 en COMMITED-READ, wat daarvoor (5.0) geen probleem gaf. Maar daar gaat het nu even niet over.
    Ik hebben een voorbeeld gemaakt met een autoincrement veld als primary en andere velden twee velden. Nu weet ik dat ik het eerste veld moet overslaan.
    De eerste record gaat goed, maar de tweede record geeft een key violation. Er is nog een applyupdates() gedaan. Nu heb ik in de providerdataset de updatemode op 'upWhereKeyOnly' gezet. De drie velden in de fieldlist van de clientdataset geplaatst en de autoincrement veld op 'autogeneratedvalue = arAutoInc' gezet. Maar dat mocht niet baten.
    Wat moet ik doen om toch records in mijn TClientdataset te zetten met een autoincrement veld?
    Delphi is great. Lazarus is more powerfull

  2. #2
    Ik zet meestal tijdelijk -RecNo in de primary key zodat de ClientDataSet er in ieder geval even blij mee is. Door de sleutel niet mee te nemen in de update (de provideroptions van het veld op de server) maakt het niet uit wat er in wordt gezet, het wordt toch nooit opgeslagen.
    Marcel

  3. #3
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Bedankt marcel. Eigenlijk is de TClientdataset dan niet zo slim. Vele databases maken gebruik van zo'n veld en had daarmee moeten worden omgegaan, zodat je niet steeds van die 'rare' handelingen moet uitvoeren om meerdere records te mogen opslaan.
    Delphi is great. Lazarus is more powerfull

  4. #4
    En hoe los je het op wanneer er sprake is van een master/detail relatie waarbij de masterkey van de detailtabel het autoincrement veld van de master is. Zolang er nog geen applyupdates hebben plaatsgevonden is deze waarde dus nog niet bekend.

  5. #5
    Dit is natuurlijk volledig logisch als je het concept van een clientdataset begrijpt. De kracht daarvan is nl dat je geen cursor in je database open hoeft te houden. Bij de meeste middleware oplossingen heb je hetzelfde probleem.

    Zelf pas ik een vergelijkbare truc toe als Marcel. Bij mij op de server vervang ik dan het tijdelijke ID door een echt database ID (Midas kan vast ook wel zoiets).

    Heb ik een uitgebreide MD relatie, of meerdere, die ineens gepost moeten worden dan gebruik ik een service op mijn server. Die kan ik vanaf de client aanroepen om mij een uniek nieuw id te geven.

    Mijn framework heeft verder een voorziening waarbij de client een soort voorraad kan vragen van unieke ID"s aan de server.

    Ik denk dat je bij gebruik van de CDS of een middleware framework gewoon geen gebruik moet maken van een autoincrement veld (die stammen nog uit de dbf tijd, toen alle apps een cursor open hielden in de database).

  6. #6
    Counting your refs Paul-Jan's Avatar
    Join Date
    Feb 2002
    Location
    Lage Zwaluwe
    Posts
    2,160
    Mijn framework heeft verder een voorziening waarbij de client een soort voorraad kan vragen van unieke ID"s aan de server
    .

    Hier idem. Al proberen we dat meestal impliciet te houden.

  7. #7
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Quote Originally Posted by Benno View Post
    Ik denk dat je bij gebruik van de CDS of een middleware framework gewoon geen gebruik moet maken van een autoincrement veld (die stammen nog uit de dbf tijd, toen alle apps een cursor open hielden in de database).
    Hoezo? De meeste databaseservers (behalve Oracle) hebben een autoincrement in zich en worden nog steeds ondersteund. Sterker nog, ik lees af en toe nog wel eens een artikel, waarin staat dat auto-increment goed is om een unieke key te registreren.
    Volgens mij heeft DBF niet eens auto-increment.
    Delphi is great. Lazarus is more powerfull

  8. #8
    John,

    Ik heb alleen aan willen geven dat het oude techniek is. Je gaat ook geen cursors open houden in de database (als je slim bent).

    Het mooie van dingen als de clientdataset en middleware frameworks is dat je een offline model hebt. Schalen van je oplossingen wordt zo ook makkelijker.

  9. #9
    En inderdaad, autoincrements zijn bijzonder handig maar ze kunnen je ook heel erg in de weg zitten. Vooral als je met een offline systeem wilt werken. Dan is een primary key waarvan je zelf de teller bijhoudt een stuk eenvoudiger.

    Je kunt dan, indien nodig, op de client je servermethod PrimKey(string: TableName) aanroepen en deze alvast vullen. Met een autoincrement is dat een stuk lastiger.
    Marcel

  10. #10
    TDigitalTrain user Hans Brenkman's Avatar
    Join Date
    Mar 2002
    Location
    Weert
    Posts
    1,861
    Quote Originally Posted by jkuiper View Post
    De meeste databaseservers (behalve Oracle) hebben een autoincrement in zich
    Volgens mij heeft ook FireBird geen autoincrement maar wordt daar een generator voor gebruikt, in Oracle een sequence genoemd. Autoincrement lijkt me eerder een uitzondering in een RDBMS (al lijkt MySQL en MS SQL server het ook te hebben) of heb ik het mis ?
    Testen kan niet de afwezigheid van fouten aantonen, slechts de aanwezigheid van gevonden fouten.

    Het is verdacht als een nieuw ontwikkeld programma direct lijkt te werken: waarschijnlijk neutraliseren twee ontwerpfouten elkaar.

  11. #11
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    MySQL heeft het inderdaad en al een hele tijd.
    Ook Marcel heeft gelijk. Omdat clientdataset offline werkt, is het moeilijk te bepalen welke waarde ingevoerd moet worden om toch synchroon te blijven met de database.
    Delphi is great. Lazarus is more powerfull

  12. #12
    TDigitalTrain user Hans Brenkman's Avatar
    Join Date
    Mar 2002
    Location
    Weert
    Posts
    1,861
    Ik vul een ID altijd in het OnBeforePost-event. Als het ID leeg is (is alleen bij een nieuw record), haal ik een nieuw ID op, aangeleverd door de database.

    Ik doe dus wel altijd na een record ingevoerd te hebben een Applyupdates, en heb dus nooit een set nieuwe records in een CDS met allemaal een leeg ID.
    Testen kan niet de afwezigheid van fouten aantonen, slechts de aanwezigheid van gevonden fouten.

    Het is verdacht als een nieuw ontwikkeld programma direct lijkt te werken: waarschijnlijk neutraliseren twee ontwerpfouten elkaar.

  13. #13
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Maar dan heb je toch geen profijt van de clientdatasets?
    Delphi is great. Lazarus is more powerfull

  14. #14
    TDigitalTrain user Hans Brenkman's Avatar
    Join Date
    Mar 2002
    Location
    Weert
    Posts
    1,861
    Hoe bedoel je ?

    In feite hoeft de OnBeforerPost niet eens (althans niet om het ID te bepalen) want op het ID-veld staat een trigger die, indien de waarde van het ID veld NIL c.q. leeg is, meteen het ID bepaald a.d.h.v. de sequence c.q. generator.

    [EDIT]De reden dat ik dat doe is simpel; op de 1e plaats wil ik een ingevoerd record ook direct vastgelegd hebben in de database, dat lijkt me toch niet zo vreemd. In mijn apps is het gebruikelijk dat een CDS maar één record bevat (afgezien van DBgrids en lists e.d.), het records dat bewerkt wordt. Op de 2e plaats gebeurd het hier dat gebruiker 1 een record invoerd en gebruiker 2 een paar minuten later met het ingevoerde record verder gaat. Dus zal dat record bekend moeten zijn in database want gebruiker 2 dient dat record op te halen voordat die er mee aan de slag kan.[/EDIT]
    Last edited by Hans Brenkman; 02-Feb-09 at 12:33.
    Testen kan niet de afwezigheid van fouten aantonen, slechts de aanwezigheid van gevonden fouten.

    Het is verdacht als een nieuw ontwikkeld programma direct lijkt te werken: waarschijnlijk neutraliseren twee ontwerpfouten elkaar.

  15. #15
    John,

    Je moet denk ik proberen een mindswitch te maken tussen een online model en een offline model.

    Bij een online model heb je een constante connectie naar de database, je hebt dan ook een aantal cursors open in de database, per gebruiker. Alle acties die je op je dataset doet hebben dan direct een invloed op de database. Bij zo'n online model zie je ook vaak heel veel business logica in de database zitten, bv in stored procedures.

    Bij een offline model (zoals de CDS, maar ook veel middleware) heb je maar hele korte contactmomenten met de database. Je haalt op wat je nodig hebt, waarna de "connectie" met de database weg is. Connectie staat tussen aanhalingstekens omdat je meestal niet de hele connectie opnieuw zult opbouwen, maar ik bedoel daarmee dat je geen cursors in de database gaat openhouden. Bij een offline model zul je dus de meeste business logica in je delphi code hebben. Pas na een update naar een database (bv via applyupdates) zullen de wijzigingen doorgevoerd worden naar de database.

    Een offline model is vaak beter schaalbaar, omdat je simpelweg minder connecties naar de database hebt. Je middleware laag kun je ook makkelijker schalen, bv door ze te verdelen over meerdere servers en een loadbalancer te gebruiken.

    Zoals je aangeeft kan het een nadeel zijn dat je dingen als een autoinc field van de database niet meer kunt gebruiken. Maar daar kun je in je framework gewoon omheen werken, een PK is immers niet meer dan een uniek nummertje wat verder geen enkele functionele toepassing zou moeten hebben. Het is dus geen probleem om bv aan je database alvast 10 of 100 Id's te vragen voor je client, de nummers hoeven immers ook niet oplopend in de database te staan.

Page 1 of 3 1 2 3 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •