2016-12-28 1 views
1

삭제 :는 다음과 같이 나는 테이블 <strong>upload_temp</strong>이 재귀 PostgreSQL을

CREATE TABLE upload_temp (
    codigo serial PRIMARY KEY NOT NULL, 
    codigo_upload_temp_pai INTEGER, 
    nome TEXT NOT NULL, 
    codigo_extensao INTEGER, 
    data_inclusao TIMESTAMP NOT NULL DEFAULT NOW(), 
    codigo_usuario_inclusao INTEGER NOT NULL, 

    CONSTRAINT fk_upload_upload_pai FOREIGN KEY (codigo_upload_temp_pai) REFERENCES upload_temp (codigo) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE, 
    CONSTRAINT fk_extensao_upload FOREIGN KEY (codigo_extensao) REFERENCES extensao (codigo) MATCH SIMPLE ON UPDATE CASCADE ON DELETE NO ACTION, 
    CONSTRAINT fk_usuario_upload FOREIGN KEY (codigo_usuario_inclusao) REFERENCES usuario (chave) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE, 
    CONSTRAINT uq_upload UNIQUE('nome', COALESCE('codigo_extensao', -1), COALESCE('codigo_upload_temp_pai', -1), 'codigo_usuario_inclusao', DATE(data_inclusao)) 
); 

이 테이블 저장 내 시스템의 모든 임시 업로드,이 업로드 폴더파일 수 있습니다. 테이블의 자체 참조 기능이이를 처리합니다. 하지만 문제는 : 어떤 파일이 시스템에 등록되면 공식 디지털 파일이되고 upload_temp이 삭제됩니다. 삭제할 때 상위 폴더는 빈 폴더가 될 때만 삭제해야합니다. 이렇게하면, 유일한 자식을 잃어서 비어있는 한이 트리에서 모든 폴더를 삭제해야합니다. 다음 그림은 자세한 내용을 포함

Tree of folders and files

파일 5.jpg는폴더 4, 등등에 속하는 폴더 5에 속한다. 파일 5.jpg을 시스템에 등록하도록 선택하면 upload_temp에서 삭제되며 폴더 5이 비어 있습니다. 따라서 폴더 5이 비어 있으면 삭제해야하며이 경우 모든 상위 폴더에도 동일한 작업이 수행됩니다.

비록 PHP를 사용하고 있지만 성능을 목표로하는 PostgreSQL의 솔루션이 필요합니다. WITH RECURSIVE의 작동 방식을 이해하려고하는데 어려움을 겪고 있습니다.

WITH RECURSIVE all_uploads (codigo, parent, ext, main) AS (
    SELECT ut1.codigo, ut1.codigo_upload_temp_pai AS parent, ut1.codigo_extensao AS ext, ut1.codigo AS main 
    FROM upload_temp ut1 

    UNION ALL 

    SELECT ut2.codigo, ut2.codigo_upload_temp_pai AS parent, ut2.codigo_extensao AS ext, au.main 
    FROM upload_temp ut2 
    JOIN all_uploads au ON au.parent = ut2.codigo 
) 
DELETE FROM upload_temp WHERE codigo IN (SELECT codigo FROM all_uploads WHERE codigo = 486); 

다음 그림은 SELECT * FROM upload_temp ORDER BY codigo의 결과를 보여줍니다 :

나는 비어있는 기능을 무시하고 파일 5.jpg부터 재귀 적으로 모든 부모를 제거하도록되어 다음과 같은 코드를 작성 Select result

음, 작동하지 않습니다. 하나의 파일 만 삭제하고 있습니다. 이 문제를 해결하려면 어떻게해야합니까? 감사!

+0

이번에는 훨씬 더 분명하다. –

+0

http://stackoverflow.com/a/37288233/267540 – e4c5

+0

스크린 샷에는 크기가 'tamanho'인 열이 있지만 정의가 아닙니다. –

답변

0
WITH RECURSIVE all_uploads (codigo, parent, ext, main) AS (
SELECT ut1.codigo, ut1.codigo_upload_temp_pai AS parent, 
    ut1.codigo_extensao AS ext, ut1.codigo AS main 
FROM upload_temp ut1 
WHERE ut1.codigo = 486 

UNION ALL 

SELECT ut2.codigo, ut2.codigo_upload_temp_pai AS parent, 
ut2.codigo_extensao AS ext, au.main 
FROM upload_temp ut2 
JOIN all_uploads au ON au.parent = ut2.codigo 
) 
DELETE FROM upload_temp WHERE codigo IN (SELECT codigo FROM all_uploads); 

당신은 (와 내부의) 초기 선택의 시작점을 넣어이 있거나 어떻게 든 "나무"의 상단을 나타내는 의사 열을해야, 그것은 그 전체의 모든 행에 대해 동일합니다 나무. 와 함께 내부의 초기 선택에서 "상단"을 넣는 것이 더 쉬운 솔루션입니다.

+1

PERFECT! 고마워 친구! – Siipe

+0

감사합니다. 그것이 효과가 있다면 답을 받아 들여라. –