0

며칠 전에 PostgreSQL에서 WITH RECURSIVE을 사용하여 삭제에 관한 질문을했습니다. 이 :특정 조건을 고려한 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이면이므로 폴더가 비어 있습니다. 그리고 자체 참조 기능 (폴더 및 파일에 대해 동일한 DB 테이블)을 사용하여이 파일이 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; 

CYA :

여기 당신이 필요로 정확히 수행하는 기능입니다!

+0

awesome! 감사! – Siipe