webForumDet fria alternativet

Rekursiv sqlfråga med inskickat id?

Databaser & SQL

10 svar · 679 visningar · startad av Kuckel

Medlem sedan jan. 2002104 inlägg
Frågan#1

Skulle behöva lite hjälp med att skapa en rekursiv SQL-Fråga till Sql2000.

Har en tabell i databasen kallad pages i den finns pageid och parentid (NULL) ser ut så här:

pageid 4 (parent NULL)
--- pageid 5
------ pageid 6

pageid 10 (parent NULL)
-- pageid 11

Jag skulle vilja ha ut alla pages rekursivt från databasen baserat på ett inskickat pageid.

Vill kunna visa någonting så här: sidnamn id4/undersida id5/undersida id6

Men jag vill kunna skicka in t ex pageid 6 och få ram id rekursivt pageid 4-5-6

Hoppas ni förstår :)

Medlem sedan apr. 2006409 inlägg
#2

Hur måga nivåer ska du ha i sidstrukturen?

Offtopic: Hur binder du samman sida med rätt parent?

Medlem sedan jan. 2002104 inlägg
#3

Kan i princip vara oändligt antal nivåer. databasstrukturen ser ut så här

PageID | ParenID | PageName
1 ------ NULL ----- Startsida
2 ------ NULL ----- Om oss
3 ------ 2 ----- Om oss undersida 1
4 ------ 2 ----- Om oss undersida 2
5 ------ 4 ----- Under om oss undersida

Detta kopplas samman med en Teleriks RadMeny

Medlem sedan apr. 2006409 inlägg
#4

Okej, hur tänker du göra din meny? div ul eller på något annat sätt?

Medlem sedan jan. 2002104 inlägg
#5

div´s och UL

Medlem sedan apr. 2006409 inlägg
#6
function makeMenu($parent = 0)
{
   $query = mysql_query("SELECT PageID, PageName FROM Pages WHERE ParentID ='".$parent."'") or die(mysql_error());  
   if (mysql_num_rows($query) > 0)
   {
      $list = "<ul>";
      while ($res = mysql_fetch_assoc($query))
      {
         $list .= "<li>".$res['PageName'];
         $list .= makeMenu($res['PageID']);
         $list .= "</li>";
      }
      $list .= "</ul>";
   }
   else
   {
      $list = "<p>Inga rader kunde hämtas</p>";
   }
   return $list;
}

Du kan få en knuff i rätt riktning. Låt 0 betyda grundnivå, i stället för NULL alltså. Nu får du lägga in <a href=""></a> där de ska vara, jag orkade inte tänka ut det på rak arm. *Funderar* Det kan bli lite trixigt om du vill att grundnivåerna ska vara klickbara. Då får du lägga in lite if-satser i koden. Lek med den och se vad du får fram.

Edit, rättade stavfel som kanske förvirrade.

Medlem sedan jan. 2002104 inlägg
#7

Tackar .. just den biten har jag fått att fungera men jag skulle vilja ha sqlfrågan. Har testar denna men får inte riktigt ihop det

CREATE PROC dbo.ShowHierarchy
(
@Root int
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @pageID int, @EmpName varchar(30)

SET @EmpName = (SELECT menutitle FROM dbo.pages WHERE pageid = @Root)


SET @pageID = (SELECT MIN(pageid) FROM dbo.pages WHERE pageid = @Root)

WHILE @pageID IS NOT NULL
BEGIN
	EXEC dbo.ShowHierarchy @pageID
	SET @pageID = (SELECT MIN(pageid) FROM dbo.pages WHERE parentid = @Root AND parentid \> @pageID)
END

END
GO

Medlem sedan apr. 2006409 inlägg
#8

Eh... fast "just den biten" gör allt du behöver för att skriva ut en lista till webläsaren. Gör om min kod till asp eller vad det är du kör så är det bara att sql-fråga efter parent, id och namn från dbo.pages så ska du se att det löser sig.

Medlem sedan jan. 2002104 inlägg
#9

Så här fick det bli, tack för hjälpen. Du fick mig i rätt riktning

Private Sub IterateThroughParentNodes(ByVal SelectedPageID As Integer)
        dt = GetListForSiteMap() '//Hämtar en datatable
        Dim ParentRows() As DataRow = dt.Select("[Parentid] is null ")
        For Each dRow As DataRow In ParentRows

            If CInt(dRow("pageid")) = SelectedPageID Then
             '//Om topnoden är den valda sidan
                IsParent = True
                SelectedParentNodeID = dRow("pageid")
            End If

            sb.Append("<b>" & dRow("menutitle") & "</b><br>" & vbCrLf)
            IterateThroughChildrenNodes(dRow("pageid"), SelectedPageID)
            If ISParent Then
                SelectedParentNodeID  = dRow("pageid")
            End If
        Next
        Me.Literal1.Text = sb.ToString
    End Sub

    Private Sub IterateThroughChildrenNodes(ByVal ParentID As Integer, ByVal SelectedPageID As Integer)

        Dim rootRows() As DataRow = dt.Select("[Parentid] = " & ParentID & "")
        For Each dr As DataRow In rootRows

            If CInt(dr("pageid")) = SelectedPageID Then
                IsParent = True
            End If

            sb.Append(dr("menutitle"))
            IterateThroughChildrenNodes(dr("pageid"), SelectedPageID)

        Next

    End Sub
Medlem sedan apr. 2006409 inlägg
#10

Nu till nästa fråga:

Har du någon backup, ifall det inte går att få kontakt med databasen? Testa genom att köra meny-scriptet utan kontakt med databasen. Jag gjorde själv en meny som fick ligga helt och hållet i en sql-tabell. Webbhotellet är helt okej, men ett par tre gånger om året strular det med kontakten. Vad jag kan se så har du inget stop vad fel, så din sida visas nog, men utan meny. Besökarna kommer att bli förvirrade om det strular med databasen.

Medlem sedan jan. 2002104 inlägg
#11

Njae ingen backup mer än att jag har ett cachat dataset. Hela sajten är ett cms-system så funkar inte kontakten med databasen så e´det nog kört :)

Denna kod ska ligga i en serverkontrol där det finns lite mer felhantering

259 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
118 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)