2016-05-16 6 views
1

Ich habe Tabelle comment, und ich möchte durch die Eingabe löschen id und auch alle Kind löschen,löschen/wählen Hierarchiedaten in postgresql

unter zwei Abfrage beide nicht alle Hierarchiedaten löschen, löschen nur sich selbst und ein Kind Reihe ...

Gibt es etwas falsch, wenn rekursive in with Schließung auswählen?

Kommentar

id | parent_comment_id 
1 | 
2 | 1 
3 | 2 
4 | 

Abfrage 1

WITH RECURSIVE coH AS (
    SELECT co.id, 
    co.id AS rootId 
    FROM comment co 

    UNION ALL 

    SELECT coChild.id, 
    coChild.parent_comment_id as parentCommentId 
    FROM comment coChild 
    JOIN coH coP ON coP.id = coChild.parent_comment_id 
) 
DELETE FROM comment WHERE id IN (
    SELECT id FROM coH WHERE rootId = $1 
) 

Abfrage 2

DELETE FROM comment WHERE id IN (
    WITH RECURSIVE coH AS (
    SELECT co.id, 
     co.id AS rootId 
     FROM comment co 

    UNION ALL 

    SELECT coChild.id, 
     coChild.parent_comment_id as parentCommentId 
     FROM comment coChild 
     JOIN coH coP ON coP.id = coChild.parent_comment_id 
) 

    SELECT id FROM coH WHERE rootId = $1 
) 

UPDATE

var dbQuery = `DELETE FROM comment WHERE id IN (
    WITH RECURSIVE coH (id, parentCommentId, rootId) AS (
    SELECT co.id, 
     co.parent_comment_id as parentCommentId, 
     co.id AS rootId 
     FROM comment co 

    UNION ALL 

    SELECT coChild.id, 
     coChild.parent_comment_id as parentCommentId, 
     coP.rootId 
     FROM comment coChild 
     JOIN coH coP ON coP.id = coChild.parent_comment_id 
) 

    SELECT id FROM coH WHERE rootId = $1 
)`; 
+0

Ihre Anfragen scheinen korrekt, aber Löschung in der falschen Reihenfolge Fremdschlüssel Verletzungen verursachen kann. Sie können dies lösen, indem Sie keinen Fremdschlüssel haben (nicht empfohlen!) Oder indem Sie Ihren Fremdschlüssel mit ON DELETE CASCADE oder DEFERRABLE haben. –

+0

@ZiggyCrueltyfreeZeitgeister Ich fand diese Antwort http://stackoverflow.com/a/10381384/5593189 Ich aktualisiere in meiner Frage, es funktioniert, um alle zu löschen, aber ich weiß nicht warum? Was ist 'coH (id, parentCommentId, rootId)' Klammer für? und im ersten Teil wählen Sie mit warum co.parent_comment_id als ElternCommentId? – user1575921

+0

@ZiggyCrueltyfreeZeitgeister Ich habe den Fremdschlüssel in der Kommentartabelle nicht gesetzt. kann ich 'comment.parent_comment_id' fk' comment.id' setzen? Wenn die Spalte Null sein könnte, kann der Fremdschlüssel trotzdem gesetzt werden? – user1575921

Antwort

1

es einfach halten, setzen Sie den Parameter in der ersten Abfrage von rekursiven mit:

with recursive cbase as (
    select 1 as id -- select $1 as id 

    union all 

    select child.id 
    from comment as child 
    join cbase on cbase.id = child.parent_comment_id 
) 
delete from comment 
where id in (select * from cbase) 
returning id; 

id 
---- 
    1 
    2 
    3 
(3 rows) 

DELETE 3  
+0

danke für die Antwort und Beispielcode! 'Wählen Sie 1 als ID 'oder' Wählen Sie $ 1 als ID '? Ich möchte immer noch wissen, warum meine Abfrage nicht funktioniert, was ist anders zwischen meiner ursprünglichen Abfrage und Update-Abfrage, damit es funktioniert? – user1575921

+1

Ihre Abfrage funktioniert nicht gut, da einige Zeilen in der where-Klausel entfernt werden. Mit dieser Bedingung erhalten Sie immer nicht mehr als zwei Zeilen. 'select 1 ...' ist nur ein Beispiel, um die Abfrage zu testen, Sie sollten 'select $ 1 ...' natürlich verwenden. – klin

+0

Ich bekomme den Fehler 'Operator existiert nicht: text = integer' ...' JOIN co ON co.id = child.parent_comment_id' ?? – user1575921