Results 1 to 9 of 9

Thread: MySQL Dataset read only after Join

  1. #1
    Registered User
    Join Date
    Aug 2017
    Posts
    4
    Blog Entries
    1

    MySQL Dataset read only after Join

    Ik worstel al enige tijd met MySql en Foreign Keys in Lazarus 1.6.4
    Dit heb ik nu voor elkaar, maar nu is mijn Dataset read-only en kan ik duswel kijken, maar niet toevoegen of wijzigen.

    Mijn oplossing in een testomgeving met een TSQLQuery component is :

    Select *
    from relatie
    Inner Join adres On relatie.adresid = adres.adresid
    Inner Join phone On relatie.phoneid = phone.phoneid
    Inner Join phonetype On phone.phonetypeid = phonetype.phonetypeid


    Iemand enig idee hoe dit op te lossen?

    Het verwijderen van de Inner Joins lost het probleem op, maar dan weer geen Foreign Keys

    In afwachting van suggesties etc.

    Ronald Heemeijer

  2. #2
    I7 7700K 32Gb Win10 Pro Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    1,988
    Een Select * is een niet zo'n elegante toepassing voor een querie, dan kan je net zo goed een mater-detail gebruiken.

    Gecombineerde Queries kunnen heel lastig zijn.
    Een oplossing kan zijn om de tabellen separaat te updaten, er zijn mooie oplossingen.

    Hier wat studiemateriaal:
    Database Design, Getting_Started_with_Base, Sql Queries

    Gr.Peter

    Op de valreep zie ik 1 post onder je naam, een nieuw lid , welkom :-)
    Last edited by Wok; 27-Aug-17 at 11:29.
    10.3.3, Delphi2010, of Lazarus 2.0.10

  3. #3
    Registered User
    Join Date
    Aug 2017
    Posts
    4
    Blog Entries
    1
    Bedank Wok voor de snelle reactie

    Ik zal in de loop van de dag de url bekijken of dit een oplossing is.

    In een ander oplossing heb ik de gerelateerde tabellen apart zitten filteren, maar dit komt de snelheid niet ten goede/

  4. #4
    Eerst even de uitleg waarom je query read only is.
    Een update statement kan maar één tabel tegelijk updaten.

    Normaal zal de TSQLQuery bij een SELECT * FROM TABLE automatisch de InsertSQL, DeleteSQL en UpdateSQL in kunnen vullen. Maar als je een join gebruikt zijn er dus meerdere velden uit verschillende tabellen. Die kunnen dus niet met één UpdateSQL e.d. geupdate worden. Vandaar dat UpdateSQL etc. niet gevuld worden. Dat is dan ook de reden waarom je query read-only is.

    Nu is het zo dat je bij bijvoorbeeld de volgende query/dbgrid wel zelf iets kan doen:
    SQL Code:
    1. SELECT R.NAAM, R.TELEFOON, L.LAND
    2. FROM RELATIE R
    3. LEFT JOIN LAND L ON L.ID=R.LAND_ID
    Bij deze query geef je bijvoorbeeld de landnaam weer terwijl je in relatie alleen de id hebt staan van het land.
    In dat geval zou je in UpdateSQL handmatig het volgende kunnen zetten:
    SQL Code:
    1. UPDATE LAND
    2. SET NAAM=:NAAM, TELEFOON=:TELEFOON
    3. WHERE NAAM=:OLD_NAAM AND TELEFOON=:OLD_TELEFOON
    (beter natuurlijk om met relatie ID te werken maar dit is maar een voorbeeld)

    Je query wordt daarna in één keer wel updatable. Landnaam kun je echter niet updaten omdat deze niet in de update-sql staat. (landnaam wordt ook uit een andere tabel gehaald)
    Extra info op de volgende pagina
    http://wiki.freepascal.org/Working_W..._of_parameters

    Nu echter jouw query... Die haalt niet één waarde voor een zoektabel uit een andere tabel maar is een compleet master/detail dataset zoals Peter al aangaf. Je zou hier op dezelfde manier die UpdateSQL kunnen vullen maar daarmee kun je maar één tabel updaten. Je zou in dat geval dus ALLEEN de velden van RELATIE kunnen updaten in je grid en niets kunnen doen met je adres, telefoon en telefoontype. Vandaar dat dit soort queries alleen gebruikt worden voor het genereren van overzichten/lijsten en niet voor direct updatable regels. Je zult bijvoorbeeld in je lijst ook zien, dat als je twee adressen aan een relatie hebt hangen, de relatie-regel/gegevens er twee keer in staan met verschillende adressen. Leuk voor een lijst maar onzinnig voor een update-scherm.

    1) Master/detail gegevens worden dan ook meestal in 2 of meer DBGrid (met corresponderende SQLQueries).
    Zo heb je bovenin een scherm met alle relaties, daaronder een grid met adressen en daaronder een grid met telefoonnummers. Als je in het bovenste grid een relatie kiest wordt automatisch (via de externe-TDataSource-property van de TSQLQuery) de telefoon- en adresgrid gevuld met alle telefoonnummers en adressen van die relatie. En die zijn allemaal updatable.

    2) Nu zou het kunnen zijn dat je zegt dat er maar één adres en één telefoon per relatie kan zijn. In dat geval zou je je database aan kunnen passen dat deze velden direct in de RELATIE tabel staan (dat is het makkelijkste) of je moet onder je DBGrid een scherm maken, waar allerlei TDBEdits in staan zodat je na het opslaan zelf kunt zorgen dat er met een juiste update de goede tabellen geupdate worden. (Dit zou in een apart scherm kunnen staan maar kunnen ook losse TDBEdits zijn onder de DBGrid)

    Master/Detail scherm voorbeeld (1):
    Click image for larger version. 

Name:	VucTJNY.png 
Views:	68 
Size:	15.7 KB 
ID:	7623

    Voorbeeld met tdbedits onder een grid (2):
    Click image for larger version. 

Name:	v2qbRxX.png 
Views:	70 
Size:	33.9 KB 
ID:	7624

  5. #5
    Als ik me niet vergist is het met de devart data access componenten wel mogelijk om een join te inserten/update.

    p.s. de kans is redelijk groot denk ik dat de JKuiper dezelfde JKuiper is als op het nldelphi form

  6. #6
    Quote Originally Posted by luigi View Post
    Als ik me niet vergist is het met de devart data access componenten wel mogelijk om een join te inserten/update.
    Dat lijkt mij sterk. Wat vul je dan bij UpdatingTable in. Mij lijkt dit hetzelfde als zelf een UpdateSql schrijven voor één van de tablets uit de SQL. Het updaten van meerdere tables lijkt mij dan ook niet mogelijk.

    Yes, you can do it. You can use the UpdatingTable property to specify the table to be updated.

  7. #7
    In KBMMW is het zeker mogelijk om joins te inserten/updaten/deleten. Je hebt daar een property waar de tabelnaam/namen instaan en indien nodig kun je ook de field origins zetten. (bijvoorbeeld als de twee tabellen eenzelfde kolomnaam hebben of in het geval van een alias). Wat ik toen begreep van UNIDAC is dat dit op ongeveer dezelfde manier werkt, maar daar heb ik zelf geen ervaring mee.

  8. #8
    Registered User
    Join Date
    Aug 2017
    Posts
    4
    Blog Entries
    1
    Hallo Rik,

    Hartelijk dank voor de duidelijke uitleg, en mogelijke oplossing.

    Select * from tabel is natuurlijk een grove benadering, maar in mijn test wel de snelste om iets even te testen.

    Het is alleen de bedoeling om de gerelateerde master/detail gegevens te tonen en vandaar per tabel te wijzigingen of iets per tabel toe te voegen
    De bedoeling is echt niet om al deze gegevens tegelijkertijd te wijzigen of er iets aan toe te voegen.


    Ik ga zeker experimenteren met de geboden oplossing.
    Last edited by RJP; 27-Aug-17 at 18:18. Reason: aanhef vergeten

  9. #9
    Registered User
    Join Date
    Aug 2017
    Posts
    4
    Blog Entries
    1
    Hallo Luigi,

    Hartelijk dank voor je reacties.

    In de komende dagen ga ik daar zeker mee aan de slag en ik houd jullie op de hoogte van mijn vorderingen.

Thread Information

Users Browsing this Thread

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

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
  •