0

前幾天我問了一下使用WITH RECURSIVE和PostgreSQL中刪除的問題。有:DELETE遞歸PostgreSQL的尊重特定的條件

DELETE recursive PostgreSQL

這工作正常:意向,最初,是遞歸只要最終孩子被刪除,刪除父文件夾。下圖描述它更好:

Files tree view

通過刪除文件5.JPG,所有父文件夾,在這種情況下,將被刪除。

但是現在,我必須刪除父文件夾,只有當它們變空,即失去其唯一的孩子。我試過如下:

WITH RECURSIVE all_uploads (codigo, parent, ext, uploader) AS (
    SELECT ut1.codigo, ut1.codigo_upload_temp_pai AS parent, ut1.codigo_extensao AS ext, ut1.codigo_usuario_inclusao AS uploader 
    FROM upload_temp ut1 
    WHERE ut1.codigo = 576 

    UNION ALL 

    SELECT ut2.codigo, ut2.codigo_upload_temp_pai AS parent, ut2.codigo_extensao AS ext, ut2.codigo_upload_temp_pai AS uploader 
    FROM upload_temp ut2 
    JOIN all_uploads au ON au.parent = ut2.codigo 
    WHERE (SELECT ut3.codigo FROM upload_temp ut3 WHERE ut3.codigo_upload_temp_pai = ut2.codigo LIMIT 1) IS NULL 
    AND ext IS NULL 
    AND uploader = 1535 
) 
DELETE FROM upload_temp WHERE codigo IN (SELECT codigo FROM all_uploads); 

我想檢查,如果一個文件夾爲空,唯一的辦法是進行分選考慮自我的關係。如果SELECT ut3.codigo FROM upload_temp ut3 WHERE ut3.codigo_upload_temp_pai = ut2.codigo LIMIT 1) IS NULL回報真正,所以該文件夾爲空。並通過使用自參照功能(文件夾和文件相同的數據庫表),我知道這是通過檢查codigo_extensao場(僅適用於文件具有擴展名)的文件夾。

好,它不工作,它僅刪除我的5.JPG。任何提示?提前致謝!

回答

0

像你想你不能遞歸刪除。這裏的邏輯是創建一個查詢,刪除所有你想要的,並遞歸運行它,直到有更多東西要刪除。

這裏是一個函數,不正是你所需要的:

CREATE OR REPLACE FUNCTION p_remove_empty_folders(_codigo_usuario_ integer) RETURNS integer AS $$ 
DECLARE 
    AFFECTEDROWS integer; 
BEGIN 

    WITH a AS (
    DELETE FROM upload_temp WHERE codigo IN (SELECT ut1.codigo FROM upload_temp ut1 WHERE ut1.codigo_usuario_inclusao = _codigo_usuario_ AND ut1.codigo_extensao IS NULL AND NOT EXISTS (SELECT * FROM upload_temp ut2 WHERE ut2.codigo_upload_temp_pai = ut1.codigo)) 
    RETURNING 1 
    ) 
    SELECT count(*) INTO AFFECTEDROWS FROM a;  

    WHILE AFFECTEDROWS > 0 LOOP 

     WITH a AS (
     DELETE FROM upload_temp WHERE codigo IN (SELECT ut1.codigo FROM upload_temp ut1 WHERE ut1.codigo_usuario_inclusao = _codigo_usuario_ AND ut1.codigo_extensao IS NULL AND NOT EXISTS (SELECT * FROM upload_temp ut2 WHERE ut2.codigo_upload_temp_pai = ut1.codigo)) 
     RETURNING 1 
     ) 
     SELECT count(*) INTO AFFECTEDROWS FROM a; 

    END LOOP; 

    RETURN 0; 
END; 
$$ LANGUAGE plpgsql; 

氰!

+0

真棒!謝謝! – Siipe