我正在尝试将表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 :(得分:1)
假设表 设置为自动缩进:
,此解决方案可以正常工作-- 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
答案 1 :(得分:0)
假设表未设置为auto-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