Avatar billede sovetryne Nybegynder
02. oktober 2003 - 09:49 Der er 29 kommentarer og
1 løsning

The right SQL Statement

It seems I am the first on the Internet having a problem with this. So either I am trying something impossible, or I am so stupid that nobody needs to write it down on any homepage.

My problem is some SQL-statement.
I am writing a forum (www.denemarken.prikbord.franl.dk). I use VBScript / ASP as language, and Microsoft Access 2000 as database. I am having MDAC 2.8 installed on my server.
The table in the database has following fields:

- ID (AutoNumber)
- ReplyID (= 0 if a new message is postet, or "ID" of the original message, if the message is a reply)
- BaseID (ID of the first message in a topic range
- Date
- Time
- Subject
- Text
- IP
- Name
- Email
- Position

All subjects are ordered by reply, which means, that a reply on a message appears in a list right under the original message, with to spaces ( in front of the subject. And if there comes a reply on a reply, it simply adds two more spaces, and appears right under the last message.

Such as these:

Message (ID:1, ReplyID:0, BaseID: 1)
--Re: Message (ID:2, ReplyID:1, BaseID: 1)
----Re: Message (ID:3, ReplyID:2, BaseID: 1)

Now comes the tricky part. Look at this:

Message (ID:1, ReplyID:0, BaseID: 1)
--Re: Message (ID:2, ReplyID:1, BaseID: 1)
----Re: Message (ID:3, ReplyID:2, BaseID: 1)
------Re: Message (ID:4, ReplyID:3, BaseID: 1)
--------Re: Message (ID:5, ReplyID:4, BaseID: 1)
----Re: Message (ID:6, ReplyID:2, BaseID: 1)
------Re: Message (ID:7, ReplyID:6, BaseID: 1)
--------Re: Message (ID:8, ReplyID:7, BaseID: 1)
------Re: Message (ID:9, ReplyID:6, BaseID: 1)
--------Re: Message (ID:10, ReplyID:9, BaseID: 1)

Now my question is: WHICH SQL Statement am I supposed to use? At this moment, I am using

Select ID, ReplyID, Name, Email, IP, Subject, Text, Date, Time, Position, BaseID from forum ORDER BY BaseID, Position, Date, Time ASC

Yours,

Albert van Harten
Denmark

(Svar må gerne være på dansk, jeg har bare skrevet det her på engelsk, det er mere overskueligt for mig)
Avatar billede themepark Nybegynder
02. oktober 2003 - 09:58 #1
Må man godt lige starte med at spørge om hvad Position betyder? :)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 10:20 #2
Selvfølgelig :)
Position er bare antallet på mellemrum (eller bindestreg) foran subjectet.
Hvis et indlæg er et nyt emne, så er "position" 1, det vil sige: ingen bindestreg/mellemrum foran emnet. Hvis der kommer et svar, så står svaret i listen under det oprindeligt med to bindestreg foran, for at indikere at emnet er et svar. Position = 2
Hvis der kommer et svar på svaret, så får dén besked FIRE bindestreg, og Position = 3. Osv osv osv.

Så:
"position - 1  = antallet af bindestreg/mellemrum foran emnet *2"

Albert
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 10:28 #3
Message (ID:1, ReplyID:0, BaseID: 1, Position = 1)
--Re: Message (ID:2, ReplyID:1, BaseID: 1, Position = 2)
----Re: Message (ID:3, ReplyID:2, BaseID: 1, Position = 3)
------Re: Message (ID:4, ReplyID:3, BaseID: 1, Position = 4)
--------Re: Message (ID:5, ReplyID:4, BaseID: 1, Position = 5)
----Re: Message (ID:6, ReplyID:2, BaseID: 1, Position = 3)
------Re: Message (ID:7, ReplyID:6, BaseID: 1, Position = 4)
--------Re: Message (ID:8, ReplyID:7, BaseID: 1, Position = 5)
------Re: Message (ID:9, ReplyID:6, BaseID: 1, Position = 4)
--------Re: Message (ID:10, ReplyID:9, BaseID: 1, Position = 5)
Avatar billede themepark Nybegynder
02. oktober 2003 - 10:29 #4
Hmm...og her havde jeg lige regnet med at jeg ville fortælle dig hvordan du også fandt ud af antallet af bindestreger, men det HAR du jo klaret *g* ;)

Jeg skal nok lige prøve at kigge på det, men det skal vist lige siges, at man ikke, som jeg ellers startede med at tro, bare kan sortere på ID. Dit eksempel kan jo også se sådan ud (med ændrede ID og ReplyID's :)

Message (ID:1, ReplyID:0, BaseID: 1)
--Re: Message (ID:2, ReplyID:1, BaseID: 1)
----Re: Message (ID:3, ReplyID:2, BaseID: 1)
------Re: Message (ID:6, ReplyID:3, BaseID: 1)
--------Re: Message (ID:10, ReplyID:6, BaseID: 1)
----Re: Message (ID:4, ReplyID:2, BaseID: 1)
------Re: Message (ID:5, ReplyID:4, BaseID: 1)
--------Re: Message (ID:8, ReplyID:5, BaseID: 1)
------Re: Message (ID:7, ReplyID:4, BaseID: 1)
--------Re: Message (ID:9, ReplyID:7, BaseID: 1)

Men som sagt...jeg prøver at kigge på det :)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 10:44 #5
Nej, jeg prøvede også med at sortere på ID, men så snart der kommer to svar på ét indlæg, og på begge to svar svares igen, går det galt.
Du kan se hvor langt jeg er kommet på www.denemarken.prikbord.franl.dk, men den side er desværre på hollandsk... Men nu handler det ikke om beskederne, men om listen, så jeg går ud fra at det ikke gør noget.

Men tak i hvert fald at du gider kigge på det :)

Albert
Avatar billede themepark Nybegynder
02. oktober 2003 - 11:15 #6
Det her er måske ikke ligefrem den mest elegante løsning, men jeg kan ikke umiddelbart se at du skulle kunne gøre det med 1 SQL sætning, så her er hvad jeg har kogt i gryden :)

Dim PostSaet(1)
Dim AntalPostSaets
Dim SQL
AntalPostSaets=1
SQL="SELECT BaseID FROM forum WHERE ReplyID=0 ORDER BY BaseID"
PostSaet(1)=Database.Execute(SQL)
Do Until PostSaet(AntalPostSaets).EOF
  Response.Write 2*(PostSaet(AntalPostSaets)("Position")-1) &
  If PostSaet(AntalPostSaets("ReplyID")>0 Then
    Response.Write "Re: "
  End If
  Response.Write "Message (ID:" & PostSaet(AntalPostSaets)("ID") & ", ReplyID:" & PostSaet(AntalPostSaets)("ReplyID") & ", BaseID: " & PostSaet(AntalPostSaets)("BaseID") & ")"
  SQL="SELECT * FROM forum WHERE BaseID=" & PostSaet(1)("BaseID") & " AND ReplyID=" & PostSaet(AntalPostSaets)("ID") & " ORDER BY ID"
  PostSaet(AntalPostSaets).MoveNext
  AntalPostSaets=AntalPostSaets+1
  PostSaet(AntalPostSaets)=Database.Execute(SQL)
Loop

Jeg er måske lidt ude at svømme nu, dels fordi jeg ikke kan teste det, og dels fordi jeg tager det sådan lidt på rygraden, men det burde virke :)
Avatar billede themepark Nybegynder
02. oktober 2003 - 11:30 #7
Hov nu kom jeg lidt for hurtigt af sted :)

I stedet for

Response.Write 2*(PostSaet(AntalPostSaets)("Position")-1) &

skriver du

For Taeller=1 To (PostSaet(AntalPostSaets)("Position")-1)
  Response.Write "--"
Next
Response.Write 2*(PostSaet(AntalPostSaets)("Position")-1)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 12:13 #8
Jeg skal teste det senere på dagen. Skal nu først prøve at finde flere kunder for min nye virksomhed :) Tusind tak for hjælpen, indtil videre, du hører fra mig om det hjalp....

Og eh... elegant eller ej, så længe det virker, er målet nået.

Hilsen,
Alert
Avatar billede themepark Nybegynder
02. oktober 2003 - 12:17 #9
He he...dig kan jeg lide...du tænker i de samme baner som mig (elegantheden forstås) :)
Avatar billede erikjacobsen Ekspert
02. oktober 2003 - 12:25 #10
Overvej funktionen String, der giver dig et antal ens tegn i en streng:

    a=String(10, "-")

så er a="----------"
Avatar billede themepark Nybegynder
02. oktober 2003 - 12:32 #11
erikjacobsen he he...af nøjagtigt den grund oprettede jeg følgende link:

http://www.eksperten.dk/spm/408609

Efter at have fået at vide af medions at der ikke var en sådan funktion var jeg jo nødsaget til bare at bruge en tæller ;)

Men sovetryne, erikjacobsen har faktisk ret...erstat hellere

For Taeller=1 To (PostSaet(AntalPostSaets)("Position")-1)
  Response.Write "--"
Next

med

Response.Write String(PostSaet(AntalPostSaets)("Position")-1, "--")

En smule effektivitet gør jo ingen skade ;)
Avatar billede erikjacobsen Ekspert
02. oktober 2003 - 12:35 #12
Det skal vist være

Response.Write String(2*(PostSaet(AntalPostSaets)("Position")-1), "-")
Avatar billede themepark Nybegynder
02. oktober 2003 - 12:40 #13
erikjacobsen nej på ingen måde...for hver gang Position bliver en større, vil han skrive 2 "-"

02/10-2003 10:28:11

Position=1 ""
Position=2 "--"
osv :)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 12:40 #14
Jeg bruger bindestreg i mit eksempel, fordi jeg viste ikke om dette forum støtter mellemrum i starten af en linie, men på det forum jeg skriver bruger jeg 2x mellemrum ( ). Men det er ligegyldigt.

Erikjacobsen, storbytossen, har I måske MSN? Så er det nemmere at kontakte hinanden. Jeg kan findes på sovetryne001@hotmail.com, efter jeg har hentet min svigersøster :)

Albert van Harten
Avatar billede themepark Nybegynder
02. oktober 2003 - 12:43 #15
MSN Messenger har jeg da, ja, men jeg kan ikke bruge det på min skole, hvor jeg altid er, hvis jeg er på nettet :/
Avatar billede erikjacobsen Ekspert
02. oktober 2003 - 12:48 #16
Jeg tror nu nok jeg har ret mht String-funktionen:

  MyString = String(10, "ABC")  ' Returns "AAAAAAAAAA".

siger de kloge. MS-hvadfornoget? Nej, lad os da diskutere dine problemer her.
Avatar billede themepark Nybegynder
02. oktober 2003 - 12:53 #17
Hmm...jeg troede nu den ville udskrive hele strengen 10 gange...men hvis den ikke gør det, ja så er erikjacobsens metode faktisk den rigtige :)
Avatar billede themepark Nybegynder
02. oktober 2003 - 14:31 #18
Det er faktisk rigtigt nok...den returnerer kun det første tegn uanset hvor lang en streng man så skriver, så det ER hans ændring, du skal bruge :)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 14:47 #19
Storbytossen, det lykkes ikke.... Jeg er vist en idiot, eller blind eller noget, men EOF er ikke støttet..

    Dim conn
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.ConnectionString = "DSN=denemarken.prikbord"
    conn.Open
    Dim strSQL, rs
    Dim PostSaet(1)
    Dim AntalPostSaets
    Dim SQL
    AntalPostSaets=1
    SQL="SELECT BaseID FROM forum WHERE ReplyID=0 ORDER BY BaseID"
    PostSaet(1)=conn.Execute(SQL)
    Do Until PostSaet(AntalPostSaets).EOF
        Response.Write String(PostSaet(AntalPostSaets)("Position")-1, "  ")
        Response.Write 2*(PostSaet(AntalPostSaets)("Position")-1)
        If PostSaet(AntalPostSaets("ReplyID"))>0 Then
            Response.Write "Re: "
        End If
        Response.Write "Message (ID:" & PostSaet(AntalPostSaets)("ID") & ", ReplyID:" & PostSaet(AntalPostSaets)("ReplyID") & ", BaseID: " & PostSaet(AntalPostSaets)("BaseID") & ")"
        SQL="SELECT * FROM forum WHERE BaseID=" & PostSaet(1)("BaseID") & " AND ReplyID=" & PostSaet(AntalPostSaets)("ID") & " ORDER BY ID"
        PostSaet(AntalPostSaets).MoveNext
        AntalPostSaets=AntalPostSaets+1
        PostSaet(AntalPostSaets)=conn.Execute(SQL)
    Loop

(har ændret database til conn, da min ADO-connection hedder conn).

HJÆLP!!!

Albert
Avatar billede themepark Nybegynder
02. oktober 2003 - 14:56 #20
Heh...det er vist nærmere mig der er idioten her ;)

I de fleste sprog hedder det EOF...men ikke i ASP...der skal du i stedet for skrive AtEndOfStream :)
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 15:04 #21
Jeg prøver lige, men jeg er sikker på at jeg har brugt EOF før...
Avatar billede sovetryne Nybegynder
02. oktober 2003 - 16:56 #22
Det virker heller ikke med AtEndOfStream. Har også prøvet at ændre det til "do while not" i sted for "do until", men det giver heller ikke mening.
Har det noget at gøre med at vores recordset ikke endnu er "open"? Det har det sikkert, tror jeg, men jeg kan ikke se hvor den skal åbnes... Jeg er så dårlig til at se det med andres kode :) :) :)

Albert
Avatar billede themepark Nybegynder
02. oktober 2003 - 22:59 #23
Jeg tror, at det måske skyldes, at ASP ikke kan håndtere postsæt arrays, men jeg aner det ikke. Nå, men jeg vil prøve at køre koden selv, og se om jeg kan finde ud af det...heldigvis har jeg ikke noget liv, så jeg har masser af tid ;)
Avatar billede sovetryne Nybegynder
03. oktober 2003 - 11:24 #24
Hehehe... Ikke noget liv? Nå det skal vel ikke være helt sand?
Hvor i Danmark bor du forresten? Jeg bor i Varde.

Håber du kan finde ud af det, ellers skal du bare sende mig en e-mail (sovetryne001@hotmail.com), så kan du få hele koden.

Albert
Avatar billede themepark Nybegynder
22. oktober 2003 - 18:10 #25
Det er langt om længe lykkedes mig at få det til at virke :))))))

Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.ConnectionString = "DSN=denemarken.prikbord"
conn.Open
Dim strSQL, AntalPostSaets, rs()
AntalPostSaets = 1
ReDim rs(AntalPostSaets)
strSQL = "SELECT * FROM forum WHERE ReplyID=0 ORDER BY BaseID"
Set rs(1)=conn.Execute(strSQL)
FindPoster

Function FindPoster()
    Do Until rs(AntalPostSaets).EOF
        Response.Write String(2*(rs(AntalPostSaets)("Position")-1), 160)
        If rs(AntalPostSaets)("ReplyID")>0 Then
            Response.Write "Re: "
        End If
        Response.Write "Message (ID:" & rs(AntalPostSaets)("ID") & ", ReplyID:" & rs(AntalPostSaets)("ReplyID") & ", BaseID: " & rs(AntalPostSaets)("BaseID") & ")" & "<BR>"
        AntalPostSaets = AntalPostSaets + 1
            strSQL="SELECT * FROM forum WHERE BaseID=" & rs(1)("BaseID") & " AND ReplyID=" & rs(AntalPostSaets - 1)("ID") & " ORDER BY ID"
        ReDim Preserve rs(AntalPostSaets)
        Set rs(AntalPostSaets)=conn.Execute(strSQL)
        FindPoster
        AntalPostSaets = AntalPostSaets - 1
        rs(AntalPostSaets).MoveNext
    Loop
End Function

Jeg har omdøbt de forskellige variabler, sådan at de har de navne, du bruger. Den eneste, jeg selv har navngivet er AntalPostSaets.

Det, jeg i korte træk har gjort er at putte nogle af delene ind i en funktion, og så kalde den, hver gang, man kommer til en ny post i databasen. På den måde returneres man også til resten af koden, når man har udført funktionen.

Derudover har jeg fjernet lidt af de ting, du skrev i den sidste kode. F.eks. var det ikke nødvendigt at have både SQL og strSQL ;) Og ligeledes var linjen

Response.Write 2*(PostSaet(AntalPostSaets)("Position")-1)

heller ikke nødvendig. Den skulle tværtimod bare erstatte

PostSaet(AntalPostSaets)("Position")-1

i

Response.Write String(PostSaet(AntalPostSaets)("Position")-1, "&nbsp;&nbsp;")

Da String kun tager det første bogstav i den streng, man angiver, altså & i dit tilfælde, har jeg ledt lidt, og da man også kan bruge character codes for de forskellige tegn, har jeg brugt 160 i stedet for, hvilket lader til at være koden for &nbsp;

Det skulle vist være alt, hvad der er at fortælle :) Hvis du er i tvivl om noget skal du bare spørge løs :) Men det virker, skal det siges, i hvert fald på min computer...dog brugte jeg en lidt anden måde at koble op til en database på, da jeg ikke kender din metode.
Avatar billede sovetryne Nybegynder
24. oktober 2003 - 17:40 #26
Jamen TUSIND TAK skal du have :) Selvom jeg er nødt til at bygge om på det hele, er jeg utrolig glad for dette her. Jeg må endnu studere på det du har lavet, fordi det er (for mig altså) svært at forstå koden som er skrevet af en anden, men jeg tror det skal lykkes mig. Forresten kan du kigge med på http://www.denemarken.prikbord.franl.dk for det opdaterede projekt. Jeg ville ikke blande det sammen med det kørende forum, da der er nogle der bruger det, og jeg vil ikke at alle kommer og kigger på "mit værksted" *s*

Albert
Avatar billede themepark Nybegynder
24. oktober 2003 - 17:43 #27
Kay, men hvis der er noget du er i tvivl om, spørger du bare...du kender jo min e-mail adresse nu :)
Avatar billede sovetryne Nybegynder
24. oktober 2003 - 17:47 #28
Takker :) Jeg må bare finde ud af en masse ting, fordi indtil videre virker det kun på det første emne i databasen, på grund af
strSQL="SELECT * FROM forum WHERE BaseID=" & rs(1)("BaseID") & " AND ReplyID=" & rs(AntalPostSaets - 1)("ID") & " ORDER BY ID"
Der står rs(1), og det er statisk. Det skal jeg lave om til noget dynamisk, men det skal jeg først finde ud af.

Albert

PS Har du også MSN?
Avatar billede themepark Nybegynder
24. oktober 2003 - 18:10 #29
Hvis du kigger længere oppe, svarede jeg faktisk omkring med det med MSN. Jo, jeg har det, men det vil ikke virke på skolen :(

Den linje, du hentyder til, behøver skam ikke være dynamisk, det den gør er blot at den udvælger alle de poster, hvor BaseID er lig med det BaseID der er i det første postsæt. Altså, med rs(1) udvælges den message, der har ID 1, og derefter vælges så alle de messages, der skal være i den tråd :)
Avatar billede sovetryne Nybegynder
26. december 2008 - 16:50 #30
Hey, du Themepark, eksisterer du stadigvæk? Hvis ja, kan du så ikke sende mig din e-mailadresse?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester