我刚接触MERGE,我确定我的代码中存在一些错误。
这段代码会运行并创建我的方案:
我有两个表,一个名为TempUpsert的表填充自SqlBulkCopy操作(数亿条记录),另一个是用于索引和使用的生产数据的Sales表。
我希望将TempUpsert表与Sales表合并。
显然我做错了什么,即使是最简单的示例也会失败。
这将返回:
这段代码会运行并创建我的方案:
我有两个表,一个名为TempUpsert的表填充自SqlBulkCopy操作(数亿条记录),另一个是用于索引和使用的生产数据的Sales表。
我希望将TempUpsert表与Sales表合并。
显然我做错了什么,即使是最简单的示例也会失败。
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TempUpsert]') )
drop table TempUpsert;
CREATE TABLE [dbo].[TempUpsert](
[FirstName] [varchar](200) NOT NULL,
[LastName] [varchar](200) NOT NULL,
[Score] [int] NOT NULL
) ON [PRIMARY] ;
CREATE TABLE [dbo].[Sales](
[FullName] [varchar](200) NOT NULL,
[LastName] [varchar](200) NOT NULL,
[FirstName] [varchar](200) NOT NULL,
[lastUpdated] [date] NOT NULL,
CONSTRAINT [PK_Sales] PRIMARY KEY CLUSTERED
(
[FullName] ASC
)
---- PROC
CREATE PROCEDURE [dbo].[sp_MoveFromTempUpsert_to_Sales]
(@HashMod int)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
MERGE Sales AS trget
USING (
SELECT
--- Edit: Thanks to Mikal added DISTINCT
DISTINCT
FirstName, LastName , [Score], LastName+'.'+FirstName AS FullName
FROM TempUpsert AS ups) AS src (FirstName, LastName, [Score], FullName)
ON
(
src.[Score] = @hashMod
AND
trget.FullName=src.FullName
)
WHEN MATCHED
THEN
UPDATE SET trget.lastUpdated = GetDate()
WHEN NOT MATCHED
THEN INSERT ([FullName], [LastName], [FirstName], [lastUpdated])
VALUES (FullName, src.LastName, src.FirstName, GetDate())
OUTPUT $action, Inserted.*, Deleted.* ;
--print @@rowcount
END
GO
--- Insert dummie data
INSERT INTO TempUpsert (FirstName, LastName, Score)
VALUES ('John','Smith',2);
INSERT INTO TempUpsert (FirstName, LastName, Score)
VALUES ('John','Block',2);
INSERT INTO TempUpsert (FirstName, LastName, Score)
VALUES ('John','Smith',2); --make multiple on purpose
----- EXECUTE PROC
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[sp_MoveFromTempUpsert_to_Sales]
@HashMod = 2
SELECT 'Return Value' = @return_value
GO
这将返回:
请问我做错了什么?非常感谢。(1行受影响)
(1行受影响)
(1行受影响)消息2627,级别14,状态1,过程sp_MoveFromTempUpsert_to_Sales,第12行
违反了主键约束“PK_Sales”。无法在对象“dbo.Sales”中插入重复键。语句已终止。(1行受影响)
WHEN NOT MATCHED
等语句在任何插入操作之前进行评估,如果这是混淆的原因?并不是说一旦插入匹配行,那么将来具有相同PK的行将被视为“MATCHED”。这对于万圣节保护是必需的。 - Martin Smith