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