Toon posts:

[VB6] SQL queries in recursie aanroepen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met het maken van een programma dat SQL queries moet oproepen van gegevens die recursief zijn.

De bedoeling is dat ik met een SQL query een Hoofstuk uit een database haal. Vervolgens kan dit hoofdstuk weer een hoofdstuk bevatten.. En dit hoofdstuk kan ook weer een hoofstuk bevatten etc etc.

Wat ik nu doe is gewoon XX while loopjes maken in elkaar om dit voor elkaar te krijgen.. Maar dit is natuurlijk niet de methode die ik wil gebruiken omdat ik niet weet hoeveel hoofdstukken diep het gaat (dit is elke keer verschillend).

Het misschien een beetje onduidelijk verhaal dus hieronder een stuk code met de while loopjes in elkaar.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
strSQL = "SELECT * FROM Hoofdstuk WHERE HoofdstukId = 3"
Set Rs(0) = Db.OpenRecordset(strSQL, dbOpenDynaset)

Do While Not Rs(0).EOF
  List1.AddItem Rs(0).Fields("Titel").Value
  strSQL = "SELECT * FROM Inhoud WHERE SuperId = " & Rs(0).Fields("HoofdstukId").Value
  Set Rs(1) = Db.OpenRecordset(strSQL, dbOpenDynaset)
  Do While Not Rs(1).EOF
    strSQL = "SELECT * FROM Hoofdstuk WHERE HoofdstukId = " & Rs(1).Fields("SubID").Value
    Set Rs(2) = Db.OpenRecordset(strSQL, dbOpenDynaset)
    Do While Not Rs(2).EOF
      List2.AddItem Rs(2).Fields("Titel").Value
      strSQL = "SELECT * FROM Inhoud WHERE SuperId = " & Rs(2).Fields("HoofdstukId").Value
      Set Rs(3) = Db.OpenRecordset(strSQL, dbOpenDynaset)
      Do While Not Rs(3).EOF
        strSQL = "SELECT * FROM Hoofdstuk WHERE HoofdstukId = " & Rs(3).Fields("SubID").Value
        Set Rs(4) = Db.OpenRecordset(strSQL, dbOpenDynaset)
        Do While Not Rs(4).EOF
          List3.AddItem Rs(4).Fields("Titel").Value
          Rs(4).MoveNext
        Loop
        Rs(3).MoveNext
      Loop
      Rs(2).MoveNext
    Loop
    Rs(1).MoveNext
  Loop
  Rs(0).MoveNext
Loop


Dit effect wil ik dus ongeveer bereiken zonder elke keer hard een nieuwe while loop te moeten maken als we weer 1 hoofdstuk dieper gaan..

Ik hoop dat ik het duidelijk heb uitgelegd :o

[ Voor 7% gewijzigd door Verwijderd op 03-11-2004 14:39 ]


  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
gewoon de hele handel in een array plempen en die array recursief doorlopen, dan minimaliseer je de load op je db


voorbeeldje
ASP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sqlquery = "SELECT ID, relatieID, inhoud FROM tbl_foo;"
set objRS = objCon.Execute(sqlquery)
If Not objRS.Eof Then
  arrFoo = objRS.GetRows()
End If


function recursion(relatieID)
  dim x
  for x = 0 to ubound(arrFoo, 2)
    if relatieID = arrFoo(1, X)
       // hier je bewerkingen
       call recursion(arrFoo(0, X))
     end if
  next
end function


let op, dit is vbscript, dus dat moet je zelf maar ff porten naar VB (voor zover dat nodig is)...

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

code:
1
2
3
4
5
6
7
Sub GetHoofdstuk(id)
  'doe SQL query om hoofdstuk uit id op te halen
  If volgendHoofdstuk Then
    GetHoofdstuk(nieuwhoofdstukid)
  End If
  'wat afdrukken of een functie van maken en wat zinnigs returnen
End Sub

Vrij simpel voorbeeld van recursie eigenlijk. :)

[ Voor 21% gewijzigd door NMe op 03-11-2004 14:53 . Reden: Function -> Sub, duh :P ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Maasluip
  • Registratie: April 2002
  • Laatst online: 15:23

Maasluip

Kabbelend watertje

De oplossing van NMe84 is elegant, als je het in SQL wil doen moet je je eens inlezen op het 'connect by prior' commando. Daarmee maak je SQL queries op hierarchische (recursieve) structuren.

Signatures zijn voor boomers.


  • Haploid
  • Registratie: Maart 2002
  • Laatst online: 29-12-2021

Haploid

Doh!

Je kunt t ook prima doen met de recordsets. Ik zou alleen in alle vier de recordsets de hele tabellen ophalen en dan met de Filter property gaan weken, dus iets als:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Set Rs(0) = Db.OpenRecordset("SELECT * FROM Hoofdstuk WHERE HoofdstukId = 3", dbOpenDynaset)
Set Rs(1) = Db.OpenRecordset("SELECT * FROM Inhoud", dbOpenDynaset)
Set Rs(2) = Db.OpenRecordset("SELECT * FROM Hoofdstuk", dbOpenDynaset)
Set Rs(3) = Db.OpenRecordset("SELECT * FROM Inhoud", dbOpenDynaset)
Set Rs(4) = Db.OpenRecordset("SELECT * FROM Hoofdstuk", dbOpenDynaset)
            
Do While Not Rs(0).EOF
  List1.AddItem Rs(0).Fields("Titel").Value
  Rs(1).Filter= "SuperId = " & Rs(0).Fields("HoofdstukId").Value
  Do While Not Rs(1).EOF
    Rs(2).Filter= "HoofdstukId = " & Rs(1).Fields("SubID").Value
    Do While Not Rs(2).EOF
      List2.AddItem Rs(2).Fields("Titel").Value
      Rs(3).Filter= "SuperId = " & Rs(2).Fields("HoofdstukId").Value
      Do While Not Rs(3).EOF
        Rs(4).Filter= "HoofdstukId = " & Rs(3).Fields("SubID").Value
        Do While Not Rs(4).EOF
          List3.AddItem Rs(4).Fields("Titel").Value
          Rs(4).MoveNext
        Loop
        Rs(3).MoveNext
      Loop
      Rs(2).MoveNext
    Loop
    Rs(1).MoveNext
  Loop
  Rs(0).MoveNext
Loop


Dat is vergelijkbaar (sneller zelfs, denk ik) met werken met arrays, en een stuk minder typewerk.

Hey, I came here to be drugged, electrocuted and probed, not insulted.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Haploid schreef op 04 november 2004 @ 13:45:
Dat is vergelijkbaar (sneller zelfs, denk ik) met werken met arrays, en een stuk minder typewerk.
Sneller? Misschien...ik weet niet hoe VB is met recursie. Maar minder typewerk? Vergelijk jouw code eens met die van faabman? :X

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Haploid
  • Registratie: Maart 2002
  • Laatst online: 29-12-2021

Haploid

Doh!

NMe84 schreef op 04 november 2004 @ 15:22:
[...]
Sneller? Misschien...ik weet niet hoe VB is met recursie. Maar minder typewerk? Vergelijk jouw code eens met die van faabman? :X
Ja, nee, maar faabman z'n code doet natuurlijk niet hetzelfde. Hij heeft alleen een skelet van de code gemaakt. En wat de snelheid betreft: het belangrijkste is in dit geval dat je het aantal calls naar de database minimaliseert. Data ophalen duurt maar liefst milliseconden, zo niet langer. Al het andere werk in dit stuk code (loopen, recursie, UI vullen) valt daarbij in het niks. Dat probeerde ik te bereiken. In het originele stuk code worden heel veel afzonderlijke blokjes data opgehaald; dat kun je beter bundelen. Dat is in feite ook wat faabman deed, maar die haalde er meteen arrays bij, terwijl ik denk dat je net zo goed de recordsets zelf kunt gebruiken. Die kun je gewoon benaderen als een soort arrays en je kunt er nog op filteren ook!

Hey, I came here to be drugged, electrocuted and probed, not insulted.


  • BrZ
  • Registratie: Maart 2000
  • Laatst online: 16:16

BrZ

Haploid schreef op 04 november 2004 @ 18:41:
[...]


Ja, nee, maar faabman z'n code doet natuurlijk niet hetzelfde. Hij heeft alleen een skelet van de code gemaakt. En wat de snelheid betreft: het belangrijkste is in dit geval dat je het aantal calls naar de database minimaliseert. Data ophalen duurt maar liefst milliseconden, zo niet langer. Al het andere werk in dit stuk code (loopen, recursie, UI vullen) valt daarbij in het niks. Dat probeerde ik te bereiken. In het originele stuk code worden heel veel afzonderlijke blokjes data opgehaald; dat kun je beter bundelen. Dat is in feite ook wat faabman deed, maar die haalde er meteen arrays bij, terwijl ik denk dat je net zo goed de recordsets zelf kunt gebruiken. Die kun je gewoon benaderen als een soort arrays en je kunt er nog op filteren ook!
Ehm, jij doet 5 queries, faabman 1...
Daarnaast is jouw code eigenlijk hetzelfde als die van de TS, alleen jij kent wat variabelen voor de loops al waarden toe. Daarmee is jouw code zelfs trager, aangezien jij 5x een volledige tabel ophaalt, terwijl de TS een WHERE gebruikt, wat natuurlijk veel sneller is.
En je code is natuurlijk precies wat de TS niet wil, hij vroeg om een recursieve code om een variabel aantal hoofdstukken te hebben.

IMHO is de oplossing van NMe84 de beste, je wil bij een grote tabel echt niet eerst alle records in een array zetten, dat is ten eerste een query die veel zwaarder is dan een paar queries met een where, en daarnaast bevorderd een grote array de snelheid ook niet echt ;)

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Ik sluit me graag aan bij BrZ. Je weet niet wat sneller is tenzij je er een benchmarkje op toepast, maar ik kan je zeggen dat een 5-dubbele while met vijf gigantische recordsets niet al te best zijn voor de snelheid. :)
Haploid schreef op 04 november 2004 @ 18:41:
Al het andere werk in dit stuk code (loopen, recursie, UI vullen) valt daarbij in het niks.
offtopic:
Ik hoop dat je je ervan bewust bent dat er in de code die je postte helemaal geen recursie zat? :o

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Haploid
  • Registratie: Maart 2002
  • Laatst online: 29-12-2021

Haploid

Doh!

Ah nee, sorry, jullie hebben gelijk. Ik heb een beetje scheef naar de code zitten kijken waardoor ik de recursie er niet in herkende. My bad 8)7

Het enige argument waar ik bij blijf is dat je ernaar moet streven om het aantal keer dat je in de database kijkt, moet proberen te minimaliseren. Verder ben ik het met NMe84 en BrZ eens.

Hey, I came here to be drugged, electrocuted and probed, not insulted.


  • Zyphrax
  • Registratie: September 2001
  • Laatst online: 04-04-2023
Ermmm recursie met Database Queries?
Dat klinkt sowieso niet erg goed.

Laat de database het werk doen, niet je programma. Gebruik JOINS of SUBQUERIES om je data eerst helemaal klaar te zetten en ga er dan vanuit de code mee aan de slag.

Any sufficiently advanced technology is equivalent to magic.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Zyphrax schreef op 05 november 2004 @ 20:58:
Ermmm recursie met Database Queries?
Dat klinkt sowieso niet erg goed.

Laat de database het werk doen, niet je programma. Gebruik JOINS of SUBQUERIES om je data eerst helemaal klaar te zetten en ga er dan vanuit de code mee aan de slag.
Als je deze thread gelezen had, dan was je erachter gekomen dat recursie en meerdere queries mogelijk sneller is dan alles in één keer ophalen en opslaan in een array. Helemaal als VB net zo traag is met arrays en strings als VBScript/ASP.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1