2014-02-25 24 views
3

我試圖從表A插入行回到表A中,同時保持舊的和新的標識列。將行插入到同一個表中並存儲舊的/新的標識列

這裏是我的基本的例子:

t_course_media 
    course_media_id (PK, int, not null) -- identity column 
    course_id (int, not null) 
    media_id (int, null), 
    ... 

t_media 
    media_id (PK, int, not null), -- this is the identity column 
    ... 

我一直在問到當然媒體從3個療程複製到一個現有課程。訣竅是現有課程將需要新的media_id,以便每門課程都有獨特的t_media子行。如何從插入中維護新的media_id,以便我可以插入與剛剛插入到t_media中的新t_media行相關的正確的t_course_media行?

到目前爲止,我的研究已將我引向MERGE和OUTPUT語句。我發現樣本的問題是合併聲明一個新表。我可以使樣本正常工作,但新的media_id值從1開始(與t_media表中的xxxxx相反)。這是我發現的例子 - http://sqlblog.com/blogs/jamie_thomson/archive/2010/01/06/merge-and-output-the-swiss-army-knife-of-t-sql.aspx

DECLARE @source TABLE (
    [id] INT PRIMARY KEY, 
    [name] VARCHAR(10) 
); 

INSERT @source VALUES(1000,'Harold'),(2000,'Madge'); 

DECLARE @destination TABLE (
    [id] INT PRIMARY KEY IDENTITY(1,1), 
    NAME VARCHAR(10) 
); 

MERGE @destination 
USING (SELECT [id], [name] FROM @source) AS [source] 
ON  (1=0) --arbitrary join condition 
WHEN NOT MATCHED THEN 
    INSERT (name) 
    VALUES (source.Name) 
    OUTPUT INSERTED.id AS NEWID,[source].[id] AS OldId,INSERTED.name; 

NewID OldID name 
1  1000  Harold 
2  2000  Madge 

那麼,如何去存儲新老t_media media_id當源和目的地表是一樣的嗎?有數百行,最終我想創建一個過程來簡化過程。

+0

Couldn」你只是創建一個新表,插入記錄,然後重命名錶? –

+0

我不認爲這是可行的。這兩個表已經有成千上萬行的現有數據。我對你有正確的理解嗎? – stevewaugh76

+0

這些表沒有自動標識的原因是什麼?例如: CREATE TABLE [DBO] [t_course_media]( \t [course_media_id] [INT] IDENTITY(1,1)NOT NULL, \t [COURSE_ID] [INT] NOT NULL, \t [media_id] [INT] NOT。 NULL, – CJBS

回答

0

此解決方案假設表設置爲自動IDENT:

-- This solution assumes that all tables have 
-- auto-identity on, as per your recent comment 
BEGIN TRANSACTION insertNewCourse 

    -- For capturing newly inserted course ID 
    declare @newCourseID int 

    -- Insert new course 
    INSERT INTO [dbo].[t_course] 
       ([CourseInfo]) -- Example of other field 
     VALUES 
       ('extra field data') 

    -- Capture new ID of course 
    select @newCourseID = @@IDENTITY 

    -- INSERT new data based on selection of 3 courses by their Course ID. 
    INSERT INTO t_course_media 
    SELECT @newCourseID, media_id, SomeData 
    FROM t_course_media 
    WHERE course_id IN (2, 3, 4) -- IDs of existing 3 courses to copy 


COMMIT transaction insertNewCourse 
+0

再次感謝!我以你的答案爲基礎,非常感謝這個詳細的例子。 – stevewaugh76

+0

不客氣。很高興它的作品。 – CJBS

0

此解決方案假設表沒有被設置爲自動IDENT:

-- This solution assumes that none of these tables have 
-- auto-identity on, as per your example 
BEGIN TRANSACTION insertNewCourse 

    -- Capture max course ID 
    declare @newCourseID int 
    select @newCourseID = (max(course_id) + 1) from t_course 

    -- Insert new course 
    INSERT INTO [dbo].[t_course] 
       ([course_id] 
       ,[CourseInfo]) -- Example of other field 
     VALUES 
       (@newCourseID 
       ,'extra field data') 

    -- Capture max course_media_id 
    declare @maxCourseMediaID int 
    select @maxCourseMediaID = max(course_media_id) from t_course_media; 

    -- Use CTE to get existing data on 3 courses 
    WITH MatchingCourses_CTE (RowNum, course_id, media_id, SomeData) 
    AS 
    -- Common Table Expression (CTE) query. 
    (
     select ROW_NUMBER() 
     OVER (ORDER BY t_course_media.course_id) , course_id , media_id, SomeData -- example additional data field 
     from t_course_media  
    ) 
    -- INSERT new data based on that selected from CTE 
    INSERT INTO t_course_media 
    SELECT RowNum + @maxCourseMediaID, -- Ensure that non-auto-ident PK doesn't conflict 
      @newCourseID, media_id, SomeData 
    FROM MatchingCourses_CTE 
    WHERE course_id IN (2, 3, 4) -- IDs of existing 3 courses to copy 

COMMIT transaction insertNewCourse 
相關問題