2017-07-17 58 views
1

什麼是「深度複製」表中單個記錄的有效方法。通過「深層複製」,我的意思是創建一個新的記錄,它是原始文件的副本(除了使用新的主鍵),然後還爲每個其他表中與每個數據點關聯的每個數據點創建一個新的重複記錄原始記錄(除了這些現在將引用這個新副本)。表記錄的深層副本 - 複製記錄和所有相關數據

例如,如果有公司,部門和員工的表格,那麼對於每個公司,有多個部門,員工可能在一個或多個部門工作 - 我該如何去創建一個新公司是另一家公司的完全複製品,包括相同的部門和相同的員工(不同的主鍵除外)?

+0

是否有外鍵使用?如果是這樣,您可能需要做更多的工作,因爲您沒有複製相同的主鍵。 – Nicarus

+0

將使用外鍵,例如,如果我們複製一個公司,我們將創建新的,重複的部門,這些部門都會引用這個新公司 - 以此類推僱員。 – gilmatic

+0

這是爲了一次性練習,還是在每次插入/更新後都希望發生這種情況? – Nicarus

回答

0

不知道你的表的結構,我只能做一些假設。我會以這種方式處理它(見下文)。請注意內聯評論。

CREATE OR REPLACE FUNCTION fn_copy_company(source_company_id INT) 
RETURNS INT AS $$ 

    DECLARE new_company_id INT; 

BEGIN 

    -- Copy the company data 
    INSERT INTO companies (name) 
    SELECT name FROM companies WHERE id = source_company_id 
    RETURNING id INTO new_company_id; 

    -- Copy the departments and return the newly created record(s) as a CTE 
    WITH new_departments AS 
    (
     INSERT INTO departments (company_id, name) 
     SELECT new_company_id, name FROM departments WHERE company_id = source_company_id 
     RETURNING * 
    ) 

    -- Copy all employees belonging to the department(s) with new department ids 
    INSERT INTO employees (department_id, name) 
    SELECT 
     ndpt.department_id, 
     emp.name 
    FROM 
     new_departments ndpt 
    INNER JOIN 
     departments sdpt 
     ON (ndpt.company_id = sdpt.company_id) 
     AND (ndpt.name = sdpt.name) 
    INNER JOIN 
     employees emp 
     ON (sdpt.department_id = emp.department_id); 

    -- Returns the new company id 
    RETURN new_company_id; 

END; $$ LANGUAGE PLPGSQL VOLATILE; 

注:這裏假設你有一個ID字段具有序列表的每一個。

相關問題