Delete query met join?
ik heb twee tables, de ene heet products_categories en bevat de fields prod_id en cat_id de andere heet products (categories valt even buiten beschouwing). Die heeft de fields: id, name, content, etc. de producten worden aan categorieen gekoppeld door middel van products_categories. Nu wil ik dat wanneer ik een categorie verwijder, dat hij alle gekoppelde producten verwijderd. Ik dacht dit te doen doormiddel van de volgende code:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
mysql_query("DELETE
FROM
products
JOIN
products_categories
ON
products_categories.prod_id=products.id
WHERE cat_id=".$_GET['delete_cat']);
?>
mysql_query("DELETE
FROM
products
JOIN
products_categories
ON
products_categories.prod_id=products.id
WHERE cat_id=".$_GET['delete_cat']);
?>
Oftwel, deze regel zou alle producten moeten verwijderen waaraan een overeenkomstig cat_id is gekoppeld toch? Echter in de praktijk werkt het niet.
de $_GET['delete_cat'] verkrijgt het cat_id dat verwijdert moet worden. Dit gaat zeker weten goed.
groeten,
Martijn
Voeg even foutafhandeling toe zodat je kan zien wat er fout gaat.
De JOIN heb je dus niet nodig. Tenzij je met MyISAM-rommel ligt te rommelen, dan kan MySQL jouw data niet beschermen en zal deze er een klotezooi van maken.
Tip: Gebruik een echte database of ga met innoDB aan de slag en stel de juiste foreign keys en de juiste acties op deze FK's in.
Verder is een DELETE vrijwel gelijk aan een SELECT-query, Wanneer je "DELETE" vervangt door "SELECT *", is de boel vrij eenvoudig te debuggen zonder dat je direct data weggooit. Je krijgt dan te zien welke data er is geselecteerd en wat je dus eigenlijk weg zou willen gooien. Moet je in dit geval het resultaat wel even fetchen, anders wordt het nog niks.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
$delete_cat = intval($_GET['delete_cat'];
mysql_query("
DELETE *
FROM products
WHERE cat_id = '".$delete_cat."'");
mysql_query("
DELETE *
FROM products_categories
WHERE id = '".$delete_cat."'");
?>
$delete_cat = intval($_GET['delete_cat'];
mysql_query("
DELETE *
FROM products
WHERE cat_id = '".$delete_cat."'");
mysql_query("
DELETE *
FROM products_categories
WHERE id = '".$delete_cat."'");
?>
Lijkt mij dat dat ook gewoon met 2 kortere queries kan. Wellicht is dit nog sneller dan een JOIN of die CASCADE.
Daarnaast is jouw aanpak niet handig, hiermee kun je een leuke corrupte database oplopen wanneer er ergens iets fout gaat. Maar goed, wanneer je voor MyISAM kiest, kies je ook voor een corrupte database. Dat is vrijwel onmogelijk te voorkomen, ook al zie je dat niet direct.
Klaasjan Boven schreef op 11.09.2008 06:35:
Ik heb even opgezocht wat je met foutafhandeling bedoelt en als ik een script uit de foutafhandeling tutorial toevoeg krijg ik dit:Voeg even foutafhandeling toe zodat je kan zien wat er fout gaat.
Notice: Undefined index: delete_cat in C:\xampp\htdocs\alsa\cms\products.php on line 50
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM alsa_products JOIN alsa_products_categories ON alsa_products_categori' at line 1
kan ik persoonlijk alleen nog niet zoveel mee aangezien ik niet weet wat het betekend.
Let op dat ik ervan uitga dat de categorie gewoon een nummer (een ID) is!
Dus geen string/letters etc!!!
@ postgresql_frank: oke, dan zonder sterretje.
Wat ik niet snap ik waarom altijd alles gecontroleerd moet worden.
Het moet gewoon werken, zo niet: dan doe je iets fout.
En is je databae offline (waardoor de eerste query mislukt), dan mislukt de tweede ook gewoon.
En MyISAM is misschien niet de beste database, maar ook prima.
Net als Seat: het is geen Mercedes, maar het rijdt wel (prima).
Inderdaad zoals Eddy Erkelings zei; 2 losse queries is waarschijnlijk makkelijker :)
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
if($_GET['delete_cat']){
$deletequery = "SELECT * FROM alsa_products JOIN alsa_products_categories ON alsa_products_categories.prod_id=alsa_products.id WHERE cat_id=".$_GET['delete_cat'];
$deleteresult = mysql_query($deletequery) or die(mysql_error());
echo $deletequery;
while ($row = mysql_fetch_assoc($deleteresult)) {
echo '<br/>'.$row['cat_id'].' '.$row['name'];
}
}
?>
if($_GET['delete_cat']){
$deletequery = "SELECT * FROM alsa_products JOIN alsa_products_categories ON alsa_products_categories.prod_id=alsa_products.id WHERE cat_id=".$_GET['delete_cat'];
$deleteresult = mysql_query($deletequery) or die(mysql_error());
echo $deletequery;
while ($row = mysql_fetch_assoc($deleteresult)) {
echo '<br/>'.$row['cat_id'].' '.$row['name'];
}
}
?>
dit geeft prima waarden terug, cat_id en name staan beiden in aparte tables en worden dus dmn van prod_id en id aan elkaar gekoppeld. Werkt goed dus. Echter mijn delete query, die alle producten gekoppeld aan een cat_id moet verwijderen werkt weer niet:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['delete_cat'])){
mysql_query("DELETE FROM alsa_products JOIN
alsa_products_categories
ON
alsa_products_categories.prod_id=alsa_products.id WHERE cat_id=".$_GET['delete_cat']);
//mysql_query("DELETE FROM alsa_categories WHERE id=".$_GET['delete_cat']);
//mysql_query("DELETE FROM alsa_products_categories WHERE cat_id=".$_GET['delete_cat']);
}
die laatste 2 voor de test ff gecomment. Die werken overigens wel prima, maar bevatten ook geen join.
?>
if(isset($_GET['delete_cat'])){
mysql_query("DELETE FROM alsa_products JOIN
alsa_products_categories
ON
alsa_products_categories.prod_id=alsa_products.id WHERE cat_id=".$_GET['delete_cat']);
//mysql_query("DELETE FROM alsa_categories WHERE id=".$_GET['delete_cat']);
//mysql_query("DELETE FROM alsa_products_categories WHERE cat_id=".$_GET['delete_cat']);
}
die laatste 2 voor de test ff gecomment. Die werken overigens wel prima, maar bevatten ook geen join.
?>
em @ gast hierboven en eddy: zonder join weet ik toch niet welke producten aan mn category gekoppeld zijn? dan kan ik weinig uithalen in mn producten tabel met mn cat_id.
Gewijzigd op 01/01/1970 01:00:00 door martijn
Eddy Erkelens schreef op 11.09.2008 15:05:
Dan ben je blijkbaar geen programmeur of is het begrip "kwaliteit" jouw onbekend.Wat ik niet snap ik waarom altijd alles gecontroleerd moet worden.
Het moet gewoon werken, zo niet: dan doe je iets fout.
En is je databae offline (waardoor de eerste query mislukt), dan mislukt de tweede ook gewoon.
En MyISAM is misschien niet de beste database, maar ook prima.
Net als Seat: het is geen Mercedes, maar het rijdt wel (prima).
Het moet gewoon werken, zo niet: dan doe je iets fout.
En is je databae offline (waardoor de eerste query mislukt), dan mislukt de tweede ook gewoon.
En MyISAM is misschien niet de beste database, maar ook prima.
Net als Seat: het is geen Mercedes, maar het rijdt wel (prima).
Zowel bij Seat als Mercedes controleren ze of alles goed gaat, dat is niets bijzonders.
Maar goed, ik hou dankzij veel prutswerk van vele programmeurs een hoop werk. MyISAM draagt daar ook zijn steentje aan bij.
Hoe zou ik het volgens jou moeten aanpakken pgfrank? zie probleem hierboven.
innoDB-engine van MySQL
2) Ga foreign keys aanmaken en stel de juiste ON DELETE-actie in, CASCADE ligt voor de hand
3) "DELETE FROM products_categories WHERE id = $id" en klaar ben je. Alle producten die aan deze categorie zijn gekoppeld, worden automatisch verwijderd.
Uiteraard controleer je of de query is gelukt, foutafhandeling is de basis van ieder goed script.
1) Gebruik de 2) Ga foreign keys aanmaken en stel de juiste ON DELETE-actie in, CASCADE ligt voor de hand
3) "DELETE FROM products_categories WHERE id = $id" en klaar ben je. Alle producten die aan deze categorie zijn gekoppeld, worden automatisch verwijderd.
Uiteraard controleer je of de query is gelukt, foutafhandeling is de basis van ieder goed script.
hoe moet k een andere engine gebruiken dan :-| mijn webhost biedt mysql aan als mysql, met phpmyadmin daarbij en geen idee waar ik dat in moet stellen?