I have 2 tables:
\\d folder
Table \"public.folder\"
Column | Type |
CREATE OR REPLACE FUNCTION tree_copy(INTEGER,INTEGER) RETURNS VOID AS $$
DECLARE
a ALIAS FOR $1; --ROOT FOLDER TO BE COPIED
b ALIAS FOR $2; --DESTINATION FOLDER
i INTEGER;
j INTEGER;
g INTEGER;
BEGIN
--DROP TABLE IF EXISTS temp1;
CREATE TEMPORARY TABLE temp1 AS(
WITH RECURSIVE CTE AS(
SELECT *, NEXTVAL('folder_id_seq') new_id FROM folder WHERE id = a
UNION ALL
SELECT folder.*,NEXTVAL('folder_id_seq') new_id FROM CTE
JOIN folder ON CTE.id = folder.parent_id)
SELECT C1.id, C1.new_id, C1.parent_id,
C2.new_id new_parent_id FROM CTE C1 LEFT JOIN
CTE C2 ON C1.parent_id = C2.id);
FOR i IN (WITH RECURSIVE t AS(SELECT id, parent_id FROM folder WHERE id = a
UNION SELECT f.id,f.parent_id FROM folder f, t AS t1 WHERE f.parent_id = t1.id)
SELECT id FROM t)
LOOP
SELECT new_parent_id INTO g FROM temp1 WHERE id = i;
INSERT INTO folder(id,name,parent_id)VALUES(
(SELECT new_id FROM temp1 WHERE id = i),
(SELECT name FROM folder WHERE id = i),COALESCE(g,b));
FOR j IN (SELECT id FROM files WHERE folder_id = i)
LOOP
INSERT INTO files(id,name,folder_id) VALUES (
NEXTVAL('files_id_seq'),(SELECT name FROM files WHERE id = j),
(SELECT new_id FROM temp1 WHERE id = i));
END LOOP;
END LOOP;
DROP TABLE temp1;
END;
$$ LANGUAGE PLPGSQL;
this will do as i thought...
why do not use simple update ?
BEGIN;
UPDATE folder
SET parent_id = 3
WHERE id = 5;
UPDATE files
SET folder_id = 3
WHERE folder_id = 5;
END;