Mijn database heb ik kortweg zo opgebouwd:
Onderwerpen
id |parent_id|
1 |0
2 |0
3 |1
4 |3
In bovenstaand voorbeeld zijn 1 & 2 onderwerpen welke in het menu worden getoond, en 3 in het submenu van 1, en 4 in het submenu van 3.
Het is een duidelijk methode om mee te werken en alles lukt, behalve het verwijderen van onderwerpen inclusief alle dieperliggende pagina's. Natuurlijk kan je met een while iedere keer controleren of er dieperliggende pagina's zijn en verwijderen, maar dan moet je per laag een while doen en dat is natuurlijk niet rendabel. Graag zou ik een pure mysql oplossing vinden waarmij bovenstaand onderwerp 1, en daarmee ook 3 en 4 verwijderd kunnen worden.
Alvast bedankt!
Je kunt voor het verwijderen van dieperliggende onderwerpen een recursieve functie gebruiken:
<?php
function delete($id) {
// SELECT id FROM table WHERE idparent = $id
foreach ($result as $id) {
delete($id);
}
?>
@Tommy: liever los je het natuurlijk niet op deze manier op. De database is prima in staat om dat uit zichzelf te doen, daar hoeft helemaal geen PHP aan te pas te komen.

Naast dat je code een stuk korter wordt, is de kans op fouten ook een stuk kleiner. Wie zegt namelijk dat alle queries die jij uitvoert in je recursieve PHP functie ook daadwerkelijk lukken? Er hoeft er maar 1 te mislukken en je zit alweer met corrupte data in je database!

Kortom, laat dit gewoon lekker over aan de database...
Je kunt idd ook zo'n functie maken met MySQL (of wat anders..)
Tommy schreef op 07.07.2008 16:27
Je kunt idd ook zo'n functie maken met MySQL (of wat anders..)
Nee, je wilt hier ook in SQL geen functie voor schrijven...

Zorg gewoon dat je de juiste foreign key constraints aanbrengt en de bijbehorende acties goed instelt. Als je dan 1 (parent) record verwijderd zullen alle afhankelijke records ook verwijderd worden. It's as simple as that!
Bedankt voor jullie reacties,
@Tommy: je phpvoorbeeld zal niet werken aangezien een dieperliggend onderwerp zelf ook nog een dieper liggend onderwerp heeft. En het is de bedoeling dat ook die verwijderd worden.
Tommy's PHP voorbeeld zal wel werken, voor elk dieper liggend onderwerp wordt immers dezelfde functie uitgevoerd waarbij dus weer gekeken of er dieper liggende onderwerpen zijn.

De redenen waarom het toch niet slim is om het op deze manier aan te passen, heb ik in voorgaande posts al gegeven.
Foreign keys.

.. anders moet je maar SQL doen.


DELETE FROM category WHERE id = 3 OR parent_id = 3;
@Gerben: met die query kom je in de knoop zodra je nog een niveau dieper gaat. Die records zullen dan niet verwijderd worden waardoor je records zonder parent over houdt en je dus met corrupte data zit!

Kortom, FK's ;-)
Misschien heb ik nog een andere omweg:
<?
$id = 343; //bijv
mysql_query("UPDATE category SET parent_id = '-1' WHERE parent_id='".$id."'");
mysql_query("DELETE FROM category WHERE id = '".$id."'");
while($row = mysql_fetch_assoc("SELECT * FROM category WHERE parent_id='-1'")){
// Update waarbij alle childs van parent_id = $row['id'] worden gezet naar -1
// Delete deze $row['id'];
}
?>
Zoiets misschien?
Dan blijf je nog steeds met hetzelfde probleem zitten. Je hebt nooit de zekerheid dat alle queries lukken en als je al DELETE queries hebt uitgevoerd op het moment dat er 1 mislukt, heb je corrupte data in je database.

Dan zou je dus al met transacties moeten gaan werken, maar waarom zoveel moeite doen terwijl het met foreign keys een fluitje van een cent is? Die dingen zijn niet voor niets uitgevonden!

Reageren