[SQL] alle childs vanaf parent selecteren

Pagina: 1
Acties:
  • 295 views sinds 30-01-2008
  • Reageer

  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 13:56
Hallo allemaal,

Ik heb de volgnede tabel:

code:
1
2
3
4
5
6
7
8
9
10
11
12
NodeID          ParentNodeID
-----------     ------------
1       1           
2       1           
3       1           
4       2           
5       2           
6       3           
7       3           
8       7           
9       7           
10      8


Dit levert dan het volgende grafisch geavanceerde plaatje op:
Afbeeldingslocatie: http://www.dentol.nl/got/nodes.gif

Maar als ik een node wil verwijderen, dan moet hij ook alle child nodes verwijderen...En daar zit het probleem. Cascade delete werkt niet in met recursieve sleutels (ParentNodeID is een FK naar NodeID)

Er zijn meerdere tabellen die een koppeling hebben met NodeID, en daar werkt cascade delete prima!

Hoe kan ik een select opbouwen die bijvoorbeeld alle child nodes opleverd van NodeID 7 (dus resultaat 9,8,10)?

Ik heb het al een keer met een recursieve functie gedaan in C#, maar volgens mij is dat een beetje omslachtig...

Hoe kan ik dit nu het best doen?

Verwijderd

Recursieve stored procedure?

Verwijderd

Stel je wilt node 3 verwijderen, dan zou als ik het goed begrijp ook node 6, 7, 9, 8, 10 verwijderd moeten worden, klopt dit?

  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 13:56
recursieve stored procedure... goed plan! Maar hoe zit het dan met de waarden die hij moet terug geven? Kan je een voorbeelde geven?

  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 13:56
Verwijderd schreef op 23 November 2002 @ 17:02:
Stel je wilt node 3 verwijderen, dan zou als ik het goed begrijp ook node 6, 7, 9, 8, 10 verwijderd moeten worden, klopt dit?
Ja...Is erg lomp..maar het moet wel ja...

misschien ga ik in de toekomst nog iets met een undo functie doen....maar dat moet ik nog even bekijken...

  • Boy
  • Registratie: November 2001
  • Laatst online: 21-08 12:43

Boy

www.byoscoop.nl

Kan je niet 6 op de plaats van 3 zetten dan? Ik heb er niet veel verstand van, maar kan me herinneren dat ik hier iets van op school heb gehad...

Het had toch echt iets te maken met het wisselen van dingen...

[ Voor 19% gewijzigd door Boy op 23-11-2002 17:08 ]

Naar de bioscoop? => gebruik de app op Byoscoop.nl


Verwijderd

Ik denk niet dat het met alleen een mysql query gaat, voor welke taal is het (php, c++, vbasic....)?

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

Mij lijkt een recursieve functie toch de beste oplossing.
Cascade deleting werkt niet.

  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 13:56
[boy]
Tabel Nodes wordt gevuld door de gebruiker. menugeneratoren werken met deze gegevens...kan hierin nix verschuiven want dan verandert de site structuur

[wiseman]
Programmeer in C# en ik heb nog nooit van mySQL queries gehoort :+
De DBMS is MSSQL. Daar kan je SQL queries tegen aangooien...net zoals tegen mySQL

[robjansen]
die recursieve functie ga ik proberen in een stored prodedure te stoppen, maar ik weet nog niet hoe ik daar 1 datatable van terug moet krijgen.

  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
Ik zou geen recursieve sp gebruiken, dan loop je makkelijk tegen de nesting limiet aan. Met loopje de id's selecteren die je wilt verwijderen, in een temp-table stoppen, dan allemaal verwijderen.

Werkt die cascase delete wel als je parent-child relatie in een aparte tabel zet?

| Toen / Nu


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Als je echt puur en alleen met SQL parent child relaties op deze manier wilt terug krijgen uit je select query zal je wat anders moeten doen:

http://www.dbmsmag.com/9603d06.html
http://www.intelligententerprise.com/001020/celko1_1.shtml

Maar dat betekend wel dat je je tabel ontwerp iets om moet gooien. En het helpt niet bij het cascading delete op je eigen tabel.

We adore chaos because we like to restore order - M.C. Escher


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
je zult daar toch een level waarde aan elke node moeten hangen en per level een query 'draaien'. hoe dat je dit doet hangt van je database af (stored, subquery, IN ...).

Je kan natuurlijk ook een tabel bijhouden voor ALLE relaties maar dat word dan wel deftig groot. Het probleem dat je hebt komt overeen met XML in een SQL database te proppen - iets waar de meningen nogal uit elkaar lopen.

Persoonlijk doe ik gewoon several subqueries in zo'n geval. En aangezien in MySQL gebruik doe ik die met IN statements (sneller! omdat die op de index werkt) dan een volledige query.

Nadeel is dus wel per level / query. Maar wel eentje die sneller en sneller werkt. Vanwat ik van jouw code opmaak werk je met SQLServer dus kun je wel met subqueries werken.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Maar je weet nooit hoe diep je boom is. Als je het met subqueries doet kan je dus maximaal x levels diep...

We adore chaos because we like to restore order - M.C. Escher


  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 13:56
Zo...Na het bestuderen van een zooi pagina's over hierarchie in SQL databases, heb ik besloten dat allemaal niet te gebruiken.

De voordelen wegen niet over op tegenover de nadelen

Ik heb toch voor de C# manier gekozen.
Dit komt mede omdat ik de DAL generator van Otis gebruik. Als ik daar dan weer Stored Procedures bij moet gaan schrijven is dat niet echt bevordelijk voor het overzicht! En ik zou de heletijd de dal classes moeten aanpassen als er weer nieuwe zijn gegenereerd door LLBLGen.

Eerst had ik een uiters onflexibel systeem waarin ik zelf de kolommen van de datatable defineerde. Dat was niet echt handig.

<katja schuurman modus>
Maar nu heb ik er een, die precies doet wat ik wil!!
<katja schuurman modus>

Het is helemaal niet veel code, en hij is enorm flexibel!

PHP:
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
public DataTable getNodeMembers(int _NodeID)
{
    //init DAL
    DataAccess.Nodes oNodes = new DataAccess.Nodes();
    oNodes.NodeID = _NodeID;
    
    //maak nieuwe datatable aan van de NodeID
    DataTable dtNodes = oNodes.SelectOne();

    //dtNodes verder vullen met alle childs
    dtNodes = getNodeMember(_NodeID, dtNodes);
    
    //dtNodes terug geven
    return dtNodes;
}

private DataTable getNodeMember(int NodeID, DataTable dtNodes)
{
    //init DAL
    DataAccess.Nodes oNodes = new DataAccess.Nodes();
    
    //ParentNodeID aangeven
    oNodes.ParentNodeID = NodeID;
    
    //Alle child members van de ParentNode ophalen
    DataTable dt = oNodes.SelectAllWParentNodeIDLogic();

    foreach (DataRow Node in dt.Rows)
    {
        //child member toevoegen aan dtNodes
        dtNodes.ImportRow(Node);

        //Controleer of de child zelf een parent is, zoja
        //voer getNodeMember weer uit.
        oNodes.ParentNodeID = (int)Node["NodeID"];
        if (oNodes.SelectAllWParentNodeIDLogic().Rows.Count != 0)
            dtNodes = getNodeMember((int)Node["NodeID"], dtNodes);
    }
                
    return dtNodes;
}


Het is misschien niet de snelste manier, maar dat maakt niet uit voor de mate waarin dit gebruikt wordt.
Deze functie wordt alleen opgevraagd wanner iets verwijderd moet worden, of een soortgelijke actie...

Tell me what you think about it!

PS: Oja...er staat PHP, maar het is C#

de Code tags verneuken de layout zo erg...
[ php ] niet zo erg

[ Voor 10% gewijzigd door PhoneTech op 23-11-2002 21:12 ]

Pagina: 1