Results 1 to 12 of 12

Thread: meerdere gebruik maken van tabellen/queries in datamodule

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

    meerdere gebruik maken van tabellen/queries in datamodule

    Misschien doe ik het helemaal verkeerd en daarom vraag ik het ook.

    In mijn formulieren roep ik querycomponenten op, die nodig zijn voor dat formlier. In deze componenten staan dan ook de specifieke queries in, die het scherm vraagt. Nu heb ik een ander formulier, die 2 querycomponenten nodig heeft uit de datamodule. Maar de query in die componenten bevatten niet de juiste velden, die ik nodig hebt.
    Moet ik dan alsnog nieuwe componenten toevoegen voor dat nieuwe formulier of zijn mijn queries gewoon fout?

    Ik hoop dat het een beetje duidelijk is.
    Delphi is great. Lazarus is more powerfull

  2. #2
    Senior Member Henk Schreij's Avatar
    Join Date
    Sep 2002
    Location
    Heino (Raalte)
    Posts
    1,465
    Je kunt best querie componenten hebben waar je elke keer een andere SQL inzet, als dat het antwoord is wat je vraagt. Als je het aan een DBGrid hangt toont die elke keer andere gegevens.

    Zelf heb ik een AdsTmp die via een Dsp verbonden is aan een Cds en die weer via een Ds en DbGrid. De user kan ad-hoc velden opgeven die hij/zij wil zien.
    Ik sluit de Cds, verander de Sql in AdsTmp en open weer de Cds. En dan voila, alle gegevens staan in het DBGrid.
    Het mooie is dat de AdsTmp in een flits geopend wordt, de gegevens doorgeeft en dan zich weer sluit, zodra de gevens in de Cds staan.

  3. #3
    Hmm, runtime de queries vullen zou ik zeker niet aanraden. Dat wordt al bijzonder snel spaghetti omdat je niet meer weet waar een query voor wordt gebruikt. Als je dat wel runtime wilt doen zou ik ook geen datamodule gebruiken, maar gewoon alles runtime aanmaken. Maar naar mijn mening ga je dan wel heel erg de verkeerde kant op.

    Volgens die logica begrijp ik de vraag van jkuiper ook niet. Je tweede form heeft dezelfde query componenten nodig, maar andere velden. Dan zijn het volgens mijn logica dus andere query componenten.

    Stel dat Form1 de NAW gegevens wil tonen en Form2 de NAW gegevens en het telefoonnummer. Je zou er dan voor kunnen kiezen om twee query componenten te maken: één met de NAW gegevens en één met de NAW gegevens plus telefoonnummer. In dit geval zou ik zeggen: gebruik altijd die laatste, het meenemen van een telefoonnummer naar Form1, ook al wordt die daar niet gebruikt, is een verwaarlosbare overhead.

    Als de verschillen groter worden zou je Form2 inderdaad zijn eigen query kunnen geven. Dat is niet slecht en is geen overhead. Een gemiddeld project heeft bij mij al snel tientallen tot honderden queries, zolang je die maar goed over de datamodules verdeeld is er niets aan de hand.
    Marcel

  4. #4
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ondanks dat de zelfde tabel wordt geraadpleegd, is de query wel anders. Volgens Marcel is het dan voordeliger om een nieuwe query aan te maken.
    Stel, ik heb het volgende

    Querycomponent 1
    SELECT tbl1.id,concat(tbl2.naam,',',tbl2.voornaam) AS naamvoluit,tbl1.royalties
    FROM tbl1 JOIN tbl2 ON tbl1.id = tbl2.id;

    Querycomponent 2
    SELECT * FROM tbl1 WHERE tbl1.id = :id;

    Query 1 wordt gebruikt voor een dbgrid. De dbrid bevat dan de juiste velden voor presentatie. Query 2 wordt gebruikt om het juiste record op te roepen voor e.v.t. wijzigingen. Nu kan ik Query 2 ook gebruiken in een ander scherm. Maar omdat ik geen gegevens wijzigt en dus alleen raadpleegt, is deze query niet goed. Dan moet ik dus een nieuwe querycomponent aanmaken:

    Querycomponent 3
    SELECT * FROM tbl1

    Op zich geen probleem. Maar als ik dit ook in mijn datamodule ga zetten, vraag ik mij af of dat zinvol is. Dit component kan ook op mijn form, omdat deze de enige is die het gebruikt.
    Delphi is great. Lazarus is more powerfull

  5. #5
    select * from tbl1 is niet nodig. Je haalt dan bovendien de hele tabel op, en dat kan nogal inefficient zijn.

    In ons framework hebben we verschillende vensters met verschillende functionaliteit. Een voorbeeld:

    Een grid venster is alleen voor de weergave. Deze heeft een dataset die aan een grid hangt. Overigens gaat dit via een clientdataset. We hebben dus:
    Venster:
    - Grid, datasource, navigatiebuttons.
    Datamodule:
    - AdoDataset, provider, clientdataset
    De query die hier wordt uitgevoerd lijkt nog het meeste op jouw query 3, alleen zit er meestal wel een where aan om te voorkomen dat er teveel records in het grid komen.

    Een edit venster is iets ingewikkelder:
    Venster:
    - Edit controls, Datasource
    DataModule
    - Dataset, provider, clientdataset

    Wat? Dezelfde controls? Inderdaad. Beide schermen zijn ook afgeleid van hetzelfde basisscherm. De clientdataset is in staat om de velden in de dataset te updaten als dat nodig is. Voorwaarde is wel dat je dan niet zelf die velden berekent voor de weergave (dat kan wel in het grid scherm, waarin toch niet gewijzigd word). De query lijkt dus het meest op jouw query 2. Het record dat geëdit moet worden wordt ingeladen op basis van z'n id.

    En query 1? Tja, die zie ik niet zo vaak op die manier. In de grid-query staan weleens samengestelde velden, maar als dat op een edit venster nodig zou zijn, dan wordt dat meestal gedaan in een calculated field in de clientdataset, of met een aparte query.

    Overigens heb ik eigenlijk nooit last van de hoeveelheid datacomponenten. Elk form heeft zijn eigen datamodule. Die zijn allemaal afgeleid van verschillende basisforms en datamodules waarin steeds een stapje meer functionaliteit is geïntroduceerd. Op die manier doe je ook niet teveel werk en houd je alles generiek en gelijk.

    Vrijwel elk scherm is op die manier overzichtelijk en eenvoudige schermen zijn weliswaar heel compleet qua functionaliteit, maar hebben soms maar 3 regels code.

    Alleen complexe schermen, zoals schermen voor orders en voor producten kunnen wel uit de klauwen groeien. De resolutie van 1024x768 is dan ook niet meer genoeg, waardoor we naar tabbladen moeten grijpen. Op de datamodule zie je dat ook terug: de vele lookups, hulpqueries en natuurlijk ook andere non visual componenten tellen bij elkaar toch op tot 150 a 200 stuks.

    Niettemin geloof ik dat dit de beste oplossing is en voor zover ik weet is er maar 1 query die dynamisch wordt opgebouwd. Dat is
    Code:
    SELECT SequenceNaam.CurrVal FROM dual
    Die gebruiken we om het ID op te vragen van een zojuist ingevoegd record, en de naam van de sequence is in dit geval helaas niet als parameter mee te geven, maar verder is de query altijd hetzelfde. Daarom hebben we in dit geval een uitzondering gemaakt.

    Overigens een tip: Gebruik nooit 'select * from', maar geef altijd de veldnamen op. Als je je tabel uit gaat breiden haal je anders al die extra velden op die je toch niet gebruikt. Ik meen me nog een akkefietje te herinneren met het toevoegen van een blobveld met een image in een tabel waar toevallig wel dat * werd gebruikt...
    Zelfs in grids geldt dat 'less is more'. Voeg velden alleen toe in je grid als er ook data in staat waar je gebruikers wat aan hebben. Een teveel aan getalletjes zorgt alleen maar dat ze ze niet allemaal gebruiken.
    1+1=b

  6. #6
    Delphi & OO in Vlaanderen SamWitse's Avatar
    Join Date
    Sep 2007
    Location
    Brussel
    Posts
    833
    @John: Ik zie niet in waarom je geen TQuery zou maken per functionaliteit, ook al werken ze op dezelfde tabel: een GridQuery, een UpdateQuery, een DetailQuery.... Zo heb je ook steeds een duidelijk overzicht over de bechikbare Fields bij elke query.

    @Marcel: Wat zie jij fout aan queries die at runtime opgebouwd worden? Ik heb bijvoorbeeld een aantal zoek-criteria op mijn form, en met een "Zoek"-button wordt de query dynamisch opgebouwd aan de hand van de al-dan-niet ingevulde velden.
    Het zéér vervelende is dat, vermits de SQL pas at runtime gemaakt wordt, de fields ook niet at designtime gekend zijn, en ik bijvoorbeeld de koppeling van de fields in de DBGrid met de Query ????k telkens at runtime moet doen, ook al zijn de fields gedurende de hele leeftijd van mijn applicatie dezelfde, en verandert enkel de WHERE-clause.
    Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.

    Sam Witse.
    Delphi & OO in Vlaanderen

  7. #7
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Kortom, na de verhalen van Sam en Jos gelezen te hebben, wordt er niet echt efficiënt omgegaan met de Datamodules en TQueries. Zo zie ik het tenminste. Voor elke tabel, wat je raadpleegt heb je een aparte TQuery component. Maar waarom dan datamodules gebruiken? Om een scheiding te krijgen tussen database gerelateerde dingen en de GUI? Ik dacht dat de datamodule juist een middel was om datacomponenten te sharen over verschillende formulieren. Met het gebruik van tabellen, zoals paradox en dbf, zie ik het nut wel, maar voor Queries dan weer niet. Deze kunnen net zo goed op je form staan, omdat je ze toch maar voor dat ene formulier gebruikt worden.
    Misschien sla ik hier helemaal de plank mis. Overigens maak ik wel degelijk gebruik van datmodules, al is het alleen voor de connection naar de database en het sharen van bepaalde events, die gelijk aan elkaar zijn en hetzelfde moeten uitvoeren.
    Delphi is great. Lazarus is more powerfull

  8. #8
    Delphi & OO in Vlaanderen SamWitse's Avatar
    Join Date
    Sep 2007
    Location
    Brussel
    Posts
    833
    Je mag natuurlijk je queries op je forms plaatsen.
    Ik zie een query voor één bepaald doel, en maak er dan ook zoveel queries aan als ik 'doelen' heb.
    Het feit van de queries op een datamodule te plaatsen, heeft voor mij dan ook weinig nut in 'herbruikbaarheid', maar wel in groeperen van de logica.
    Bijvoorbeeld, als je tabelstruktuur (lichtjes) wijzigt, dan is de kans groot dat ALLE queries op die tabel aangepast moeten worden. Als al die queries op één datamodule staan, dan is dat wel even handig.
    Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.

    Sam Witse.
    Delphi & OO in Vlaanderen

  9. #9
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Daar kan ik mij wel in vinden, Sam
    Delphi is great. Lazarus is more powerfull

  10. #10
    John, het is vooral een scheiding. De datamodule is er vooral als container voor het vasthouden van al die datacomponenten. Daarbij zou je zo'n datamodule ook op zichzelf kunnen gebruiken om handelingen uit te voeren zonder form (datamodule al business object). Op die manier hebben wij het trouwens niet. We hebben ze vooral de code te splitsen in een GUI en een logica stuk, maar de scheiding is niet zo strict dat ze helemaal zonder elkaar kunnen.
    Toch is het wel handig. Zeker met complexe forms zou het gewoon te veel rommel zijn om alles in één te hebben.

    En daarbij zijn er ook datamodules die wél gedeeld worden tussen meerdere forms. Deze worden eenmalig gemaakt en gebruikt door meerdere forms. Op die datamodules staan veel gebruikte queries, algemene handelingen (zoals ook die query voor het ophalen van de sequence die ik eerder noemde), etc etc. De datamodules die bij een form horen implementeren vooral de functionaliteit die dat form wil doen. Het gebeurt niet zo vaak dat er twee forms zijn die dezelfde handeling willen doen. Gebeurt dat toch, dan heb je in een enkel geval misschien een stukje code dubbel. Niet erg, want het meeste gebeurt in stored procedures (die dan alleen op twee plaatsen aangeroepen worden). En als het meer dan een paar regels is kan het alsnog naar een aparte algemene module verplaatst worden.
    1+1=b

  11. #11
    Quote Originally Posted by SamWitse View Post
    @Marcel: Wat zie jij fout aan queries die at runtime opgebouwd worden? Ik heb bijvoorbeeld een aantal zoek-criteria op mijn form, en met een "Zoek"-button wordt de query dynamisch opgebouwd aan de hand van de al-dan-niet ingevulde velden.
    De welbekende uitzondering op de regel . Inderdaad, in dit geval zou ik de query waarschijnlijk ook runtime opbouwen. Maar dan heb je een ZoekQuery en de functionaliteit van dat ding is alles te kunnen zoeken. Dat is wat anders dan een Query1 waar soms klanten en soms facturen mee opgehaald of zelfs gewijzigd worden.
    Marcel

  12. #12
    Quote Originally Posted by jkuiper View Post
    Kortom, na de verhalen van Sam en Jos gelezen te hebben, wordt er niet echt efficiënt omgegaan met de Datamodules en TQueries.
    Het is maar wat je efficiënt noemt. Jij stelt de vraag: waarom zou je queries op een datamodule zetten, het is voor mij zo logisch dat ik mezelf de vraag niet eens stel.

    Maar het hangt er ook vanaf hoe je verder je project hebt ingedeeld natuurlijk. Als jij ook verdere code in je form zet snap ik je vraag, je bent dan toch in het form aan het coderen en dan is het bijna logisch om daar ook je query op te zetten. De enige code die bij mij in het form staat is het aanroepen van een classe die het eigenlijke werk doet, als de query dan op het form zou staan zou ik daar juist extra werk aan hebben.

    Door deze werkwijze kan ik juist wel code delen en hergebruiken en hoef ik er niet bij na te denken of ik functionaliteit X wel kan aanroepen vanaf plek Y.
    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
  •