2014-07-24 64 views
3

我有以下3個相關的表SQL:重複行以及所有相關的行

Schools   Departments   Classes 
--------------- ------------------ ----------------- 
ID    ID     ID 
School_Name  ID_Schools   ID_Departments 
        Department_Name  Class_Name 

以及他們包含內容的小樣本(我就畫我最大的努力)

---- Schools --- 
ID School_Name 
---------------- 
1 School_1 <----------------------\ 
2 School_2       | 
n ........       | 
             | 
---- Departments ----------------  | 
ID ID_Schools Department_Name  | 
---------------------------------  | 
1   1 Dept_1 <-----------/ -->--\ 
2   1 Dept_2 <-----------/ -->--|------\ 
3   2 Dept_1      |  | 
n   .. ......      |  | 
              |  | 
---- Classes -------------------    |  | 
ID ID_Departments Class_Name    |  | 
--------------------------------    |  | 
1    1 Class_1 <-------------/  | 
2    1 Class_2 <-------------/  | 
3    1 Class_3 <-------------/  | 
4    2 Class_1 <--------------------/ 
n    .. ....... 

所有ID都是自動遞增的

我正在尋找一種方法來複制'School_1'層次結構。問題是我如何維持新行之間的關係?

例如要複製'School_1'層次結構,我會在Schools表中插入一個新的原始數據,最終會生成一個新的ID(例如5)。

​​

部門的Dept_1'和 'Dept_2' 屬於 'School_1' 將獲得新的ID

---- Departments ---------------- 
ID ID_Schools Department_Name 
--------------------------------- 
16   5 Dept_1 
17   5 Dept_2 

和類也將獲得新的ID

---- Classes ------------------- 
ID ID_Departments Class_Name 
-------------------------------- 
56    16 Class_1 
57    16 Class_2 
58    16 Class_3 
59    17 Class_1 

我如何能實現這是一種簡單而智能的方式?

+2

目前無法回答此問題,但投票質疑其完美形式。我希望所有的SO問題都像這一個一樣清晰易懂! –

回答

0

我終於找到一篇文章詳細解釋了一些不同的技術來複制依賴關係的數據here

0

我建議使用SQL INSERT AS SELECT魔法,如下所述:Insert into ... values (SELECT ... FROM ...)

讓你的舊學校ID爲7,你的新學校ID爲17,那麼你可以爲每個表創建一個查詢爲INSERT INTO Departments(id, id_schools, name) VALUES (NULL, 17, (SELECT name FROM Departments WHERE id_schools = 17))

它變得有點棘手,當你需要插入類 - 通過 - 部門(多個部門),但您可以手動在WHERE id_departments IN (5,6,13, etc)填寫或者自動爲WHERE id_departments IN (SELECT id FROM Departments WHERE School_ID = 17)

PS:這更像是建議再一個答案,所以一些細節,如SQL方言或代碼質量可能不合適,但我確信方法本身。

0

我試圖爲此寫一個簡單的存儲過程。我沒有時間去測試它的邏輯,但我認爲它可以給我思考這個問題的方式。測試一下...

CREATE PROCEDURE [dbo].[copySchoolHierarchy] (@SchoolId As Int) 
As Begin 

BEGIN TRANSACTION 

BEGIN TRY 

    DECLARE @tmpSchoolName NVARCHAR(100), 
      @tmpNewSchoolID INT 

    --First insert into schools 
    SELECT @tmpSchoolName = School_Name FROM Schools WHERE ID = @SchoolId 
    INSERT INTO SCHOOLS (School_Name) VALUES (@tmpSchoolName) 
    SELECT @tmpNewSchoolID = SCOPE_IDENTITY() 

    --Then get the departments 
    INSERT INTO Departments (ID_Schools, Department_Name) 
    SELECT @tmpNewSchoolID AS someId, Department_Name FROM DEPARTMENTS Where ID_Schools = @SchoolId 

    --and the classes 
    INSERT INTO Classes (ID_Departments, Class_Name) 
    SELECT C.ID_Departments, C.Class_Name FROM Classes C 
    INNER JOIN DEPARTMENTS D ON C.ID_Departments = D.ID 
    WHERE D.ID_Schools = @tmpNewSchoolID 

    COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    --Raise some exception here... 

    ROLLBACK TRANSACTION 
END CATCH 
END 
0

這很容易複製學校和部門。要複製類,我們需要一個函數,該函數根據舊的和新的school.id值將舊的部門ID轉換爲新的部門ID。

在DEPT_ID和DEPT_NAME的情況下的組合是獨特的以下方法是可能的:

DECLARE @old_id int; // set it 

DECLARE @school_id int; 
DECLARE @school_name varchar(100); 

SET @school_name = (SELECT school_name from schools where id = @old_id); 

INSERT into schools (school_name) 
    OUTPUT Inserted.id into @school_id 
    VALUES (@school_name); 

INSERT into departments (id_schools, department_name) 
    SELECT @school_id, department_name 
    FROM departments 
     WHERE id_schools = @old_id; 

INSERT into classes (ID_Departments, Class_Name) 
    SELECT 
    (SELECT s.ID_Departments from departments s 
     WHERE s.id_schools = @school_id and s.department_name = d.department_name), 
    c.class_name 
    FROM classes c, departments d 
    WHERE c.ID_Departments = d.ID and d.ID_Schools = @old_id; 

在情況(id_schools,部門名稱)對不是唯一可以存儲部門標識在DEPARTMENT_NAME字段值臨時並更新它以後(課後創建)。