Delete query met join?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Martijn

martijn

11/09/2008 00:51:00
Quote Anchor link
Hey,

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)
PHP script in nieuw venster Selecteer het PHP script
1
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']);
?>


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
 
PHP hulp

PHP hulp

21/11/2024 20:34:54
 
Klaasjan Boven

Klaasjan Boven

11/09/2008 06:35:00
Quote Anchor link
Voeg even foutafhandeling toe zodat je kan zien wat er fout gaat.
 
Frank -

Frank -

11/09/2008 08:48:00
Quote Anchor link
Hier zijn dus foreign keys voor uitgevonden: ON DELETE CASCADE

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.
 
Eddy E

Eddy E

11/09/2008 08:56:00
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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."'");
?>


Lijkt mij dat dat ook gewoon met 2 kortere queries kan. Wellicht is dit nog sneller dan een JOIN of die CASCADE.
 
Frank -

Frank -

11/09/2008 09:03:00
Quote Anchor link
@Eddy: DELETE * bestaat niet, je kunt niet slechts een aantal kolommen verwijderen.

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.
 
Martijn

martijn

11/09/2008 14:52:00
Quote Anchor link
Klaasjan Boven schreef op 11.09.2008 06:35:
Voeg even foutafhandeling toe zodat je kan zien wat er fout gaat.
Ik heb even opgezocht wat je met foutafhandeling bedoelt en als ik een script uit de foutafhandeling tutorial toevoeg krijg ik dit:


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.
 
Eddy E

Eddy E

11/09/2008 15:05:00
Quote Anchor link
$delete_cat bestaat dus niet (of wordt niet goed ingevuld).
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).
 
Maikel

Maikel

11/09/2008 15:08:00
Quote Anchor link
Inderdaad zoals Eddy Erkelings zei; 2 losse queries is waarschijnlijk makkelijker :)
 
Martijn

martijn

11/09/2008 15:16:00
Quote Anchor link
Ik gebruik gewoon standaard mysql wat bij xampp zit als je dat bedoelt. Anyway ff wat testjes uitgevoerd, het geheel in een select query gestopt.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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'];
}
}

?>

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)
PHP script in nieuw venster Selecteer het PHP script
1
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.
?>


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
 
Frank -

Frank -

11/09/2008 16:09:00
Quote Anchor link
Eddy Erkelens schreef op 11.09.2008 15:05:
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).
Dan ben je blijkbaar geen programmeur of is het begrip "kwaliteit" jouw onbekend.

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.
 
Martijn

martijn

11/09/2008 18:37:00
Quote Anchor link
Hoe zou ik het volgens jou moeten aanpakken pgfrank? zie probleem hierboven.
 
Frank -

Frank -

11/09/2008 18:42:00
Quote Anchor link
1) Gebruik de 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.
 
Martijn

martijn

11/09/2008 19:43:00
Quote Anchor link
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?
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.