【发布时间】:2021-12-16 00:34:29
【问题描述】:
我需要在 SQL Server 中创建一个存储过程并实现一个 upsert,以便它将数据从临时表(又名源)移动到最终表(又名目标)并标记新的、更新的、未更新的行或每次新一批数据进来时都被删除。我按照here的解释使用合并。
问题在于它正在更新没有任何更改的行。我的工作流程如下:
- 将数据加载到源表中
- 调用存储过程,根据合并条件将数据从
Source移动到Target
我的存储过程如下:
CREATE PROCEDURE [dbo].[upsert_with_flag_2]
AS
DECLARE @current_time AS datetime
SET @current_time = GETDATE()
MERGE [dbo].[employee] AS Target
USING [dbo].[employee_staging] AS Source
ON Source.[first_name] = Target.[first_name]
AND Source.[last_name] = Target.[last_name]
AND Source.[dob] = Target.[dob]
WHEN MATCHED
THEN
UPDATE
SET Target.[salary] = Source.[salary],
Target.[current_address] = Source.[current_address],
Target.[is_deleted] = 'Updated',
Target.[processed_date] = @current_time
WHEN NOT MATCHED BY Target
THEN
INSERT ([first_name], [last_name],
[dob], [salary],
[current_address], [is_deleted],
[processed_date])
VALUES (Source.[first_name], Source.[last_name],
Source.[dob], Source.[salary],
Source.[current_address], 'New',
@current_time);
-- After doing upsert, check for rows whose processed date is less than current date but status is new or updated, These are
-- the rows which were not present in input file. Update there status to deleted
-- QUESTION: Should we change the processed date to current date for row's whose status is deleted?
UPDATE [dbo].[employee]
SET [is_deleted] = 'deleted'
WHERE ([is_deleted] = 'New' OR [is_deleted] = 'Updated')
AND [processed_date] < @current_time
在此之后,我执行以下步骤来加载数据并获取输出:
--Loading the initial data
TRUNCATE TABLE [dbo].[employee_staging]
GO
INSERT INTO [dbo].[employee_staging] ([first_name],
[last_name],
[dob],
[salary],
[current_address])
VALUES ('John', 'Doe', '1995-04-28', 3000, 'Andra Pradesh'),
('Robert', 'Spenser', '1994-03-28', 1800, 'Madhya Pradesh'),
('Vikash', 'Sharma', '1996-12-20', 1400, 'Uttar Pradesh'),
('Anup', 'Soni', '1994-03-28', 1800, 'Delhi'),
('Prijan', 'Sonar', '1989-01-28', 3000, 'Himachal Pradesh')
GO
EXEC upsert_with_flag
SELECT * FROM [dbo].[employee]
--Loading the updated data
TRUNCATE TABLE [dbo].[employee_staging]
GO
INSERT INTO [dbo].[employee_staging] ([first_name], [last_name],
[dob], [salary],
[current_address])
VALUES ('Robert', 'Spenser', '1994-03-28', 2000, 'Madhya Pradesh'),
('Vikash', 'Sharma', '1996-12-20', 1400, 'Maharashtra'),
('Anup', 'Soni', '1994-03-28', 1800, 'Delhi'),
('Prijan', 'Sonar', '1989-01-28', 3000, 'Himachal Pradesh'),
('William', 'Beck', '1991-04-22', 3300, 'Karnataka'),
('Robert', 'Brownie', '1986-04-22', 5000, 'Assam')
注意第 4 行和第 5 行。Anup 的输入行数据没有变化,但我仍将 [is_deleted] 列为“已更新”。我希望它类似于“现有”或“无变化”。
请帮助使这成为可能。这个 upsert 逻辑是大管道的一部分,我们需要在新文件中更新、新、未更新或删除的行。我如何做到这一点?
【问题讨论】:
标签: sql sql-server stored-procedures