Nu kommer en lurig fråga.
Hur gör man hieraki i SQL?
Säg att jag har en tabell med två fält. id och ownerid. När en post inte är ägd får den 0 som ownereid.
Hur gör jag för att skapa en tabell där hela hierakin är uppbyggd? Jag vill använda en extra kolumn för vilken position varje post har i hierakin. Den vill jag att SQL ska skapa.
Detta är för komplicerat för mig så jag hoppas någon kan hjälpa till.
Det enklaste sättet jag vet som man kan lösa det på är att köra nestade loopar.
Inte speciellt upphetsande, jag vet, och inte speciellt smidigt.
Alternativt så kanske man skulle kunna lösa det genom att göra en lagrad procedur (eh, stored procedure) som sorterar upp det hela?
Iaf, så här har jag löst det i ett forum som jag gjorde (men som jag ska göra om):
MsgLevel är på vilken "level" meddelandet är på. Är det = 1 så är det en ny tråd.
Vet inte hur självförklarande detta är.
Men du får tänka dig att det är ett forum. Koden är ju ganska rörig också (det är delvis därför jag ska göra om den)
sub step1()
dim sql, rs, rs2, id
SQL = "SELECT posts.id as pid, posts.postdate, posts.replies, posts.topic, users.[e-mail], users.name FROM posts, users WHERE posts.GroupRef = 1 AND posts.MsgRef = 0 AND posts.MsgRef = 0 AND posts.userid = users.id ORDER BY Postdate DESC"
set rs = cn.execute(SQL)
do while not rs.eof%>
<tr>
<td bgcolor="#B0B0B0"><font size="2">
<a href="default.asp?step=2&pid=<%=rs("pid")%>"><%=rs("topic")%></a> - <%=rs("postdate")%> <%=rs("replies")%> relplies / <a href="mailto:<%=rs("e-mail")%>?SUBJECT=FORUM:<%=rs("topic")%>"><%=rs("name")%></a><br>
</font>
</td>
</tr>
<%
id = rs("pid")
SQL = "SELECT posts.id as pid, posts.msglevel, posts.postdate, posts.replies, posts.topic, users.[e-mail], users.name FROM posts, users WHERE posts.GroupRef = 1 AND posts.Msgref ="&id&" AND posts.userid = users.id"
set rs2 = cn.execute(SQL)
do while not rs2.eof
dim tmp,i
for i = 1 to rs2("MsgLevel")
tmp = tmp & " "
next
%>
<tr>
<td bgcolor="#D6D6D6"><font size="2">
<%=tmp%><a href="default.asp?step=2&pid=<%=rs("pid")%>#<%=id%>"><%=rs2("topic")%></a> - <%=rs2("postdate")%> <%=rs2("replies")%> relplies / <a href="mailto:<%=rs2("e-mail")%>?SUBJECT=FORUM:<%=rs2("topic")%>"><%=rs2("name")%></a><br>
</font>
</td>
</tr>
<%rs2.movenext
tmp = ""
Loop
rs.movenext
loop%>
Man bör inte sätta nivån i tabellen. Varje inlägg ska i stället innehålla ID:t på det inlägg som besvarats.
ID, ParentID etc..
SELECT:a ut alla inlägg med ParentID 0 eller NULL. För varje rad i utsökningen söker man ut de inlägg som har det gällande ID:t som ParentID, och för varje sådant blablabla....
Det kan låta processorintensivt, men med en snabb databas, som MySQL, är det inget större problem.
Det var det kodan jag hade gjorde.
MsgRef är hur många som ligger över den.
Så tex om MsgRef är 3 så blir det 3 x " "
for i = 1 to rs2("MsgLevel")
tmp = tmp & " "
next
Så att posten läggs olika långt från kanten.
Men sedan så ska det gå att göra detta i en stored procedure. Jag sitter å knåpar på det just nu (till SQL server visserligen, men ändå). Såg något exempel i Books online där de gjorde en temporär tabell där de la in allting sorterat. Fast jag vet inte hur man ska göra för att skicka ut det som ett recordset sedan?
Vet någon så säg gärna!
Behöver jag lägga till att det redan finns en inbyggd funktion som heter MS Data Shape som man kan bygga upp hierarkier med jätte simpelet.
Det går inte, om man inte för in onödig information i databasen. Visst kan man göra rekursiva sökningar direkt i SQL....
SELECT A1.Titel from Meddelanden A1,Meddelanden A2 WHERE A1.ParentID=A2.ID
...men om man t.ex. vill lista alla meddelanden som har meddelandet 345 som rot, så går inte det, om man inte för in ID på rotmeddelandet på varje rad. Problemet är ju att varje rad som returneras måste uppfylla alla villkor i WHERE-satsen.
Därför måste man använda en rekursiva funktioner från applikationen som anropar databasen, eller en stored procedure.
En annan variant är att hämta in alla meddelanden, som ska vara med, till en array, och loopa över den rekursivt.
Det var därför jag hade MsgLevel, för att man skulle slippa göra en dynamisk nestad loop som kunde gå igenom alla de där 335 st meddelandena. Utan istället så hade jag MsgLevel som bestämde var de skulle vara i trädet.
Fast just nu sitter jag själv å pular med en stored procedure som ska göra en temporär table där den sätter upp allting som det ska vara. Sedan så loopar man bara igenom den vanligt (fast med MsgLevel fortfarande som bestämmer vilken position som den ska ligga på).
Saken är väl bara den att jag inte vet hur man ska göra för att bestämma vilken select som proceduren ska skicka tillbaka. Så att den inte skickar typ 5 recordset, det vill man ju inte :/. Om det nu ens går att bestämma det?
Är det någon som har ett exempel så får den personen kanon gärna visa den
252 ms totalt · 4 externa anrop · v20260731065814-full.d34c6d5a