Sql &引用;“合并”;使用文字值的样式操作?
我有一个包含学生成绩关系的表:Sql &引用;“合并”;使用文字值的样式操作?,sql,merge,sql-server-2008-r2,Sql,Merge,Sql Server 2008 R2,我有一个包含学生成绩关系的表: Student Grade StartDate EndDate 1 1 09/01/2009 NULL 2 2 09/01/2010 NULL 2 1 09/01/2009 06/15/2010 我正在尝试编写一个存储过程,该过程包含Student、Grade和StartDate,我希望 检查以确保这些值不重复 如果记录不是重复的,请插入该记录 如果存在现有
Student Grade StartDate EndDate
1 1 09/01/2009 NULL
2 2 09/01/2010 NULL
2 1 09/01/2009 06/15/2010
我正在尝试编写一个存储过程,该过程包含Student
、Grade
和StartDate
,我希望
EndDate=NULL
,则使用新记录的StartDate
更新该记录1
,2
,09/01/2010
,我希望最终得到:
Student Grade StartDate EndDate
1 2 09/01/2010 NULL
1 1 09/01/2009 09/01/2010
2 2 09/01/2010 NULL
2 1 09/01/2009 06/15/2010
这听起来像是我可以使用
MERGE
,只是我要传递文本值,并且我需要执行多个操作。我今天早上头痛得厉害,似乎不能清晰地思考,所以我专注于这个MERGE
解决方案。如果有更明显的方法可以做到这一点,不要害怕指出它。即使传递文字值,也可以使用合并。以下是您的问题的一个示例:
CREATE PROCEDURE InsertStudentGrade(@Student INT, @Grade INT, @StartDate DATE)
AS
BEGIN;
MERGE StudentGrade AS tbl
USING (SELECT @Student AS Student, @Grade AS Grade, @StartDate AS StartDate) AS row
ON tbl.Student = Row.Student AND tbl.Grade = row.Grade
WHEN NOT MATCHED THEN
INSERT(Student, Grade, StartDate)
VALUES(row.Student, row.Grade, row.StartDate)
WHEN MATCHED AND tbl.EndDate IS NULL AND tbl.StartDate != row.StartDate THEN
UPDATE SET
tbl.StartDate = row.StartDate;
END;
我更喜欢以下内容,它更干净,更容易阅读和修改
MERGE Definition.tdSection AS Target
USING
(SELECT *
FROM ( VALUES
( 1, 1, 'Administrator', 1, GETDATE(), NULL, Current_User, GETDATE())
,( 2, 1, 'Admissions', 1, GETDATE(), NULL, Current_User, GETDATE())
,( 3, 1, 'BOM', 1, GETDATE(), NULL, Current_User, GETDATE())
,( 4, 1, 'CRC', 1, GETDATE(), NULL, Current_User, GETDATE())
,( 5, 1, 'ICM', 1, GETDATE(), NULL, Current_User, GETDATE())
,( 6, 1, 'System', 1, GETDATE(), NULL,Current_User, GETDATE())
,( 7, 1, 'Therapy', 1, GETDATE(), NULL, Current_User, GETDATE())
)
AS s (SectionId
,BusinessProcessId
,Description, Sequence
,EffectiveStartDate
,EffectiveEndDate
,ModifiedBy
,ModifiedDateTime)
) AS Source
ON Target.SectionId = Source.SectionId
WHEN NOT MATCHED THEN
INSERT (SectionId
,BusinessProcessId
,Description
,Sequence
,EffectiveStartDate
,EffectiveEndDate
,ModifiedBy
,ModifiedDateTime
)
VALUES (Source.SectionId
,Source.BusinessProcessId
,Source.Description
,Source.Sequence
,Source.EffectiveStartDate
,Source.EffectiveEndDate
,Source.ModifiedBy
,Source.ModifiedDateTime
);
简单地说:
--Arrange
CREATE TABLE dbo.Product
(
Id INT IDENTITY PRIMARY KEY,
Name VARCHAR(40),
)
GO
--Act
MERGE INTO dbo.Product AS Target
USING
(
--Here is the trick :)
VALUES
(1, N'Product A'),
(2, N'Product B'),
(3, N'Product C'),
(4, N'Product D')
)
AS
Source
(
Id,
Name
)
ON Target.Id= Source.Id
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
Name
)
VALUES
(
Name
);
哦,太好了。我不知道您可以将文字值与合并一起使用!我尝试过类似的方法,但没有想到使用别名,这一点现在看起来很明显。这并不完全是我需要的,因为我需要在匹配时插入和更新,但我相信我可以在那里找到解决方案。它真正的关键是如何使用合并和我的值。多谢!你也可以这样使用:使用(VALUES(@Student,@Grade,@StartDate))作为[row](Student,Grade,StartDate)@Davos我真的很想看到你在回答中的评论。谢谢@yzorg,但我认为拉马克已经回答了这个问题的各个方面(不像下面的其他答案),我在这里的贡献很小。这并没有回答OP关于编写一个存储过程的问题,这个存储过程需要插入参数。这也忽略了问题的第3部分,即当结束日期为空时的更新。这个例子只会插入新记录,因此并不比insert语句更好。谢谢。你为我节省了很多时间。当您实际上没有两个表要合并,而是要合并文本或变量时,使用MERGE指令并利用干净的语法是一个很好的技巧。