[SQL] Kortere/Minder loop(s)

Pagina: 1
Acties:

  • semicon
  • Registratie: Augustus 2003
  • Laatst online: 20-08-2025
Ik ben met een vriend van mij een website aan het maken voor een clan.
Je moet er erg veel kunnen instellen en doen en alles komt uit de database, vanzelfssprekend execute je dus tig sql strings en word tje broncode extreem groot (nual 1500+ regels zonder tekst!).

Volgens een leraar op school kunnen alle SQL strings veel korter, wij gebruiken vaak tot zeker 5x Recordsets (Rs, Rs_, Rs__, Rs_1 enz) het zou wel heeel veel schelen als alles korter kan, maar met SQL hebben wij, evenals de leraar niet veel kennis.

Maar wij zien niet in dat dit korter kan,
dan vragen we het de pro's

Kan dit mischien korter? (op gebied van SQL)

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Set Rs = Con.Execute("SELECT EventMapId, MapName, MapId, TeamName, TeamId FROM adcEventsMaps WHERE EventId = " & EventId & "")
If Rs.eof Then  Print "No maps available yet."
BeginEventInfo
Do Until Rs.eof
    BeginAddEventMap FilterHTML(Rs("MapName")), FilterHTML(Rs("TeamName"))
    If Logged_Adminlevel >= 2 Then EventLoadTactic "<a href=""?action=tactic&eventid=" & EventId & "&eventmapid=" & Rs("EventMapId") & "&mapid=" & Rs("MapId") & "&teamid=" & Rs("TeamId") & """>load tactic</a>"
    '--- Assigned players loop ---
    Set Rs_ = Con.Execute("SELECT PositionId, Category, [Position] FROM adcPositions ORDER BY Category, [Position]")
    Do Until Rs_.eof
        Set Rs__ = Con.Execute("SELECT EventPositionId, MemberId FROM adcEventsPositions WHERE EventMapId = " & Rs("EventMapId") & " AND PositionId = " & Rs_("PositionId") & "")
        If Not Rs__.eof Then
            If Category <> Rs_("Category") Then
                AddEventPositionCategory FilterHTML(Rs_("Category"))
                Category = Rs_("Category")
            End If
            Do Until Rs__.eof
                If Rs__("MemberId") <> "" Then
                    Set Rs_4 = Con.Execute("SELECT Nickname FROM adcMembers WHERE MemberId = " & Rs__("MemberId") & "")
                    Nickname = "<a href=""?action=viewplayer&eventid=" & EventId & "&eventmapid=" & Rs("EventMapId") & "&memberid=" & Rs__("MemberId") & """>" & FilterHTML(Rs_4("Nickname")) & "</a>"
                Else
                    Nickname = ""
                End If
                If Rs_("PositionId") <> "" Then
                    If Logged_Adminlevel < 2 Then
                        Position = FilterHTML(Rs_("Position"))
                    Else
                        Position = "<a href=""?action=viewposition&eventid=" & EventId & "&eventmapid=" & Rs("EventMapId") & "&eventpositionid=" & Rs__("EventPositionId") & "&positionid=" & Rs_("PositionId") & """>" & FilterHTML(Rs_("Position")) & "</a>"
                    End If
                Else
                    Position = ""
                End If
                AddEventPosition Nickname, Position
            Rs__.MoveNext
            Loop
        End If
    Rs_.MoveNext
    Loop

    '--- Unassinged players loop ---
    Category = False
    Set Rs_ = Con.Execute("SELECT MemberId FROM adcEventsAU WHERE EventId = " & EventId & " AND Available")
        Do Until Rs_.eof
            Set Rs__ = Con.Execute("SELECT MemberId FROM adcEventsPositions WHERE EventMapId = " & Rs("EventMapId") & " AND MemberId = " & Rs_("MemberId") & "")
            If Rs__.eof Then
                If Not Category Then
                    AddEventPositionCategory "Unassigned"
                    Category = True
                End If
                Set Rs_4 = Con.Execute("SELECT Nickname FROM adcMembers WHERE MemberId = " & Rs_("MemberId") & "")
                    AddEventPosition "<a href=""?action=viewplayer&eventid=" & EventId & "&eventmapid=" & Rs("EventMapId") & "&memberid=" & Rs_("MemberId") & """>" & FilterHTML(Rs_4("Nickname")) & "</a>", ""
            End If
        Rs_.MoveNext
    Loop
    EndAddEventMap
    Category = ""
Rs.MoveNext
Loop


(edit kan deze code tag niet terug lopen?)
Phew :)

[ Voor 20% gewijzigd door semicon op 03-12-2003 14:31 ]


  • whoami
  • Registratie: December 2000
  • Nu online
Waarom voer je in een loop een aantal keer dezelfde query uit? Je kan die query beter 1x uitvoeren, en de resultaten ervan ergens bewaren.

Verder heb je een aantal queries die je tot 1 query kunt brengen. Lees eens iets over joins, of volg een SQL tutorial, en je zult zelf wel snappen welke queries je kunt samenvoegen.

https://fgheysels.github.io/


  • majornono
  • Registratie: Juni 2002
  • Laatst online: 04-04 23:16
je zou het vullen van RS_ een RS__ in 1 query kunnen zetten en deze buiten de loop die begint op regel 4 zetten. Dan hoeft hij ook maar 1 keer uitgevoerd te worden. Die Query ziet er dan ongeveer als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
Set Rs_ = Con.Execute("
SELECT adcPositions.PositionId, 
    adcPositions.Category, 
    adcPositions.[Position]
FROM adcPositions 
LEFT OUTER JOIN adcEventsPositions 
    ON adcEventsPositions.EventMapId = adcPositions.EventMapId 
    AND adcEventsPositions.PositionId = adcPositions.PositionId
WHERE adcEventsPositions.EventMapId = rs("EventMapId")
ORDER BY adcPositions.Category, 
    adcPositions.[Position]

Problem Exists Between Chair And Keyboard


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Denk dat je hier meer response krijgt als je even je table structuur post en welke velden je wilt selecteren volgens welke voorwaarden.

Tip: als je niet goed bent in lastige sql statements, dan is het vaak een optie om hem gewoon bij elkaar te klikken in een access view, welliswaar is dat niet optimaal, maar het is nog altijd beter als recursief zaken afhandelen door geneste loops in je code.

  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 27-05 23:18

Delphi32

Heading for the gates of Eden

Ik sluit me aan bij Raptorix hierboven, maar wil het volgende nog toevoegen in de hoop dat meer mensen er wat mee kunnen.
De regel die ik heb geleerd bij werken met SQL databases is: think big. Probeer je probleemstelling hier terug te dringen tot de essentie. Die essentie is in dit geval (als ik goed gelezen heb) dat je met 2 typen spelers 2 verschillende dingen wilt doen. Laten we dat dus eens terugbrengen tot 2 queries, om mee te beginnen: eentje die de assigned players afhandelt en eentje die de unassigned players doet. (eventueel kunnen we later die twee samenvoegen, maar ok)
Nu ga je voor die 2 queries exact opschrijven, in normale taal, wat voor gegevens je nodig hebt. Stel je voor dat je dat aan de database vraagt in het Nederlands: geef me alle spelers die in de map voorkomen, en van die spelers hun huidige positie. Ga vervolgens die nederlandse vraag rustig stukje voor stukje vertalen naar SQL. Vergeet die loops maar: een database met een fatsoenlijke query engine is vele malen beter in het oplossen van deze vraag dan loopjes. Probeer wat je wil te weten komen, te formuleren in één vraag. Dan hoef je je dus nog niet bezig te houden met de exacte tabel-definities, want dat komt pas in stap 2 (vertalen naar SQL of bijelkaar klikken in Access, goeie suggestie trouwens).
Kortom, weet wat je wilt weten voordat je een query schrijft. En vertrouw erop dat een database een goeie query vele malen sneller uit kan voeren dan jij nieuwe recordsetjes kan opbouwen.
Met dank aan Pierre Winkler, Aan de slag met SQL (ISBN 90-72260-48-1) en nee, ik heb geen aandelen bij de uitgeverij :)