Results 1 to 7 of 7

Thread: INSERT query / Unieke velden

  1. #1

    INSERT query / Unieke velden

    Beste lezer,

    Ik ben aan het overstappen van het BDE tijdperk naar Delphi 2009.
    In MySQL heb ik een aantal tabellen aangemaakt. Via DBX componenten leg ik verbinding: TSQLConnection, SimpleDataSet en TSQLQuery.

    Ik heb de boel al een beetje aan de praat gekregen en kan via de SimpleDataset al door tabellen heen scrollen.

    Wanneer ik een INSERT query maak met TSQLQuery en via EXECSQL uitvoer gaat er af en toe iets fout. Ik heb de volgende problemen:

    - Wanneer ik een record probeer in te voeren dat al bestaat en waar een unieke index opzit krijg ik een lelijke foutmelding: TDBXerror with the message 'Duplicate entry...'. Hoe kan ik deze melding netjes afvangen?? Waarom krijg ik niet gewoon een getal waardoor ik kan concluderen dat er iets niet goed gaat?

    - Ik probeer een paar 100 records over te zetten. Ik ben bang dat ik een niet optimale (ehhhhh) methode gebruik. Per regel voer ik een losse Insert Query uit. Wanneer ik een INSERT query uitvoer waarin bijvoorbeeld 20 regels zitten en er zit 1 unieke tussen dan gaat de query toch fout. Nu doe ik ze los en plaats in een loop de query tussen TRY EXCEPT...

    - Kan ik in Delphi net als in MYSQL een reeks INSERTS uitvoeren waar een ; (punt komma) achter staat. Een Transactie.

    - Of, is het beter om eerst te checken of het record er is. Bijvoorbeeld via een SELECT query en pas daarna een losse INSERT query uit te voeren.

    OK, Sorry voor mijn wellicht domme vraag. Ik heb al gezocht naar een boek over Delphi 2009 maar dat is Engels en lijkt vooral over zeer geavanceerde zaken te gaan.

    Greetings,

    Rogier

  2. #2
    Allereerst: Delphi is Delphi, ongeacht de database. Of je transactions kunt gebruiken hangt af van de database die je met Delphi gebruikt. MySQL ondersteunt dat (deels) wel, net als veel andere databases. Ik denk dat de DBX componenten ook wel een mogelijkheid bieden om de transactionele eigenschappen van een database te gebruiken. TSQLConnection heeft een StartTransaction en een Commit method. Ik denk dat je die zou moeten gebruiken.

    De fouten die je krijgt zijn te ondervangen met exception handling (try..except), of (deels) door eerst te controleren of het record al bestaat. Ook in het laatste geval zou ik die try..except nog wel gebruiken om de fout netjes af te vangen. Eventueel kun je dan namelijk je hele transaction afbreken.

    Ik weet niet precies welke exception je krijgt, maar vaak is dat een specifiek type, bijvoorbeeld:
    Delphi Code:
    1. try
    2.   ..
    3. except
    4.   on e: EDBXException do
    5.     ShowMessage(e.Message)
    6.   else
    7.     ShowMessage('Ander soort exception');
    8. end;
    Nou weet ik niet of een EDBXException bestaat, maar dat zou je misschien kunnen uitzoeken. Sommige van die specifieke exception types hebben namelijk ook extra informatie, zoals een foutcode. Op die manier kun je wellicht op een nette manier controleren wat de fout is en er een nette melding van geven.
    1+1=b

  3. #3
    Hoi,

    Bedankt voor het antwoord! Ik heb de foutmelding nu netjes afgevangen.
    Is het juist dat een transactie ongeveer het volgende is:

    een aantal SQL queries achter elkaar warabij je op het einde alles in 1x kan doorvoeren?
    Hoe voer je een transactie uit via een DBX component? Ik zie wel de mogelijkhede STARTTransaction, maar de invoer, waar specifeer ik die?

    Verder nog een vraag: Als ik eerst via SELECT check of het record/ veld al bestaat, en dan daarna een vervolgactie uitvoer: INSERT. Is dat dan niet een dubbele belasting van de database of maakt dat niet zo gek veel uit als er een index op staat?

  4. #4
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Een simpledataset wordt eigenlijk alleen gebruikt om een select uit te voeren en deze te tonen zonder er iets voor te doen (zie help). TSQLQuery is een een richtingsverkeer naar de database toe. Dat weet je ook wel, want je maakt gebruik van aparte TSQLQuery met een insert. Deze insert kan je beter gebruik maken met parameters.
    Echter is het beter om DBX te gebruiken i.c.m. met TSQLQuery <-> Datasetprovider <-> Clientdataset. Dan ben je niet meer afhankelijk van een aparte component met een query, maar laat de datasetprovider zorgen dat er netjes INSERT / UPDATE / DELETE queries worden gemaakt naar de TSQLQuery toe. Groot voordeel hiervan is: alles werkt via het RAM geheugen.
    Delphi is great. Lazarus is more powerfull

  5. #5
    Je zou inderdaad eerst kunnen controleren of een regel bestaat voordat je deze toevoegt. Aan de andere kant: waarom zou je? Als je kunt vertrouwen op je unieke sleutel is het net zo verstandig om de regel toe te voegen en de fout af te vangen.

    Het hangt er denk ik vooral vanaf wat de regel is en wat de uitzondering. Als de toe te voegen waarden in 99% van de gevallen al bestaan lijkt het me beter om eerst te controleren, als de regel maar in 1% van de gevallen zal bestaan zou ik niet eerst controleren.
    Marcel

  6. #6
    Sommige databases ondersteunen een "INSERT OR UPDATE" achtige constructie, wat inhoudt dat wanneer er een unieke key error optreedt de db zelf overgaat tot een replace van de overige values. In sommige gevallen kan dit een oplossing bieden, heb het zelf gehad in een stukje software waar ik eerst via een SELECT voor 100'en records moest controleren of de key al bestond.

  7. #7
    Ja, als dat je doel is is dat inderdaad helemaal lekker. Ik doe in dat geval meestal een UPDATE en kijk naar RowsAffected. Als die 0 is bestond de regel blijkbaar nog niet en ga ik 'm alsnog toevoegen.
    Marcel

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
  •