合并 table 与更新 ms sql

merge table with update ms sql

我需要一项更新方面的帮助 - insert with merge in sql 这里是原Insert

INSERT INTO [WarehouseMgmt].[JobSteps]
([JobId],[StepName],[StepNo],[ExecName])
VALUES
(N'HOURLY_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
(N'MANUAL_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
(N'HOURLY_JOB', N'SyncReportServerUserEntries', 4220,N'WarehouseMgmt.SyncReportServerUserEntries'),
(N'MANUAL_JOB', N'SyncReportServerUserEntries', 4220, N'WarehouseMgmt.SyncReportServerUserEntries'),
(N'HOURLY_JOB', N'SyncReportServerUsers', 4230,N'WarehouseMgmt.SyncReportServerUsers'),
(N'MANUAL_JOB', N'SyncReportServerUsers', 4230, N'WarehouseMgmt.SyncReportServerUsers'),
(N'HOURLY_JOB', N'StageFactReportServerExecutionLog', 4240, N'WarehouseStaging.StageFactReportServerExecutionLog'),
(N'MANUAL_JOB', N'StageFactReportServerExecutionLog', 4240, N'WarehouseStaging.StageFactReportServerExecutionLog'),
(N'HOURLY_JOB', N'SyncFactReportServerExecutionLog', 4250, N'WarehouseMgmt.SyncFactReportServerExecutionLog'),
(N'MANUAL_JOB', N'SyncFactReportServerExecutionLog', 4250, N'WarehouseMgmt.SyncFactReportServerExecutionLog')

INSERT WarehouseMgmt.SyncJobSteps
(
    JobStepId,
    StepType,
    SyncDataSQLId
)
SELECT 
    JobStepId = JS.Id,
    StepType = 'SQL',
    SyncDataSQLId = SSD.Id
FROM WarehouseMgmt.JobSteps JS
JOIN 
(
    VALUES
        ('SyncReportServerReports',  'WarehouseMgmt.DimReportServerReports'),
        ('SyncReportServerUserEntries',  'WarehouseMgmt.DimReportServerUserEntries'),
        ('SyncReportServerUsers',  'WarehouseMgmt.DimReportServerUsers'),       
        ('StageFactReportServerExecutionLog',  'WarehouseStaging.FactReportServerExecutionLog'),
        ('SyncFactReportServerExecutionLog',  'WarehouseMgmt.FactReportServerExecutionLog')

) V([SyncJobStep], [SQLDataObjectName])
ON JS.StepName=V.[SyncJobStep]
JOIN WarehouseMgmt.SyncSQLData SSD ON V.[SQLDataObjectName]=SSD.ObjectName

我想把这个放在我的桌子上

INSERT INTO [WarehouseMgmt].[JobSteps]
([JobId],[StepName],[StepNo],[ExecName])
VALUES
(N'HOURLY_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
(N'MANUAL_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
(N'HOURLY_JOB', N'SyncReportServerUserEntries', 4220,N'WarehouseMgmt.SyncReportServerUserEntries'),
(N'MANUAL_JOB', N'SyncReportServerUserEntries', 4220, N'WarehouseMgmt.SyncReportServerUserEntries'),
(N'HOURLY_JOB', N'SyncReportServerUsers', 4230,N'WarehouseMgmt.SyncReportServerUsers'),
(N'MANUAL_JOB', N'SyncReportServerUsers', 4230, N'WarehouseMgmt.SyncReportServerUsers'),
(N'HOURLY_JOB', N'SyncReportServerFormatEntries', 4240,N'WarehouseMgmt.SyncReportServerFormatEntries'),
(N'MANUAL_JOB', N'SyncReportServerFormatEntries', 4240, N'WarehouseMgmt.SyncReportServerFormatEntries'),
(N'HOURLY_JOB', N'SyncReportServerReportFormat', 4250,N'WarehouseMgmt.SyncReportServerReportFormat'),
(N'MANUAL_JOB', N'SyncReportServerReportFormat', 4250, N'WarehouseMgmt.SyncReportServerReportFormat'),
(N'HOURLY_JOB', N'StageFactReportServerExecutionLog', 4260, N'WarehouseStaging.StageFactReportServerExecutionLog'),
(N'MANUAL_JOB', N'StageFactReportServerExecutionLog', 4260, N'WarehouseStaging.StageFactReportServerExecutionLog'),
(N'HOURLY_JOB', N'SyncFactReportServerExecutionLog', 4270, N'WarehouseMgmt.SyncFactReportServerExecutionLog'),
(N'MANUAL_JOB', N'SyncFactReportServerExecutionLog', 4270, N'WarehouseMgmt.SyncFactReportServerExecutionLog')

INSERT WarehouseMgmt.SyncJobSteps
(
    JobStepId,
    StepType,
    SyncDataSQLId
)
SELECT 
    JobStepId = JS.Id,
    StepType = 'SQL',
    SyncDataSQLId = SSD.Id
FROM WarehouseMgmt.JobSteps JS
JOIN 
(
    VALUES
        ('SyncReportServerReports',  'WarehouseMgmt.DimReportServerReports'),
        ('SyncReportServerUserEntries',  'WarehouseMgmt.DimReportServerUserEntries'),
        ('SyncReportServerUsers',  'WarehouseMgmt.DimReportServerUsers'),
        ('SyncReportServerFormatEntries',  'WarehouseMgmt.DimReportServerFormatEntries'),
        ('SyncReportServerReportFormat',  'WarehouseMgmt.DimReportServerReportFormat'),
        ('StageFactReportServerExecutionLog',  'WarehouseStaging.FactReportServerExecutionLog'),
        ('SyncFactReportServerExecutionLog',  'WarehouseMgmt.FactReportServerExecutionLog')

) V([SyncJobStep], [SQLDataObjectName])
ON JS.StepName=V.[SyncJobStep]
JOIN WarehouseMgmt.SyncSQLData SSD ON V.[SQLDataObjectName]=SSD.ObjectName

我不能只使用 INSERT,因为数据库中已经有值而且我不想删除 them.How 我可以在我的第一个插入中更新 4 个值和 4 个新值吗?仔细看第一插入第二

我想要这样的东西

MERGE [WarehouseMgmt].[JobSteps] JS
USING #JobSteps TJS
ON(TJS.[StepName] = JS.[StepName])
WHEN NOT MATCHED BY TARGET
THEN INSERT ([JobId],[StepName],[StepNo],[ExecName]) 
VALUES 
(N'HOURLY_JOB', N'SyncReportServerFormatEntries', 4240,N'WarehouseMgmt.SyncReportServerFormatEntries'),
(N'MANUAL_JOB', N'SyncReportServerFormatEntries', 4240, N'WarehouseMgmt.SyncReportServerFormatEntries'),
(N'HOURLY_JOB', N'SyncReportServerReportFormat', 4250,N'WarehouseMgmt.SyncReportServerReportFormat'),
(N'MANUAL_JOB', N'SyncReportServerReportFormat', 4250, N'WarehouseMgmt.SyncReportServerReportFormat')
WHEN MATCHED
THEN UPDATE JS.[StepNo] = TJS.[StepNo] ;

为什么这是错误的?

您可以在 merge 语句中使用 table 值构造函数作为源 table,几乎与在 select 中使用的方式相同,因此不是:

SELECT Column1, Column2
FROM (VALUES (1, 2), (3, 4)) AS v (Column1, Column2)

您可以使用:

MERGE [TableName] AS t
USING (VALUES (1, 2), (3, 4)) AS v (Column1, Column2)
    ON t.Column1 = v.Column1
WHEN MATCHED etc...

所以对于你的第一个例子,你最终会得到:

MERGE [WarehouseMgmt].[JobSteps] AS js
USING 
(   VALUES
        (N'HOURLY_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
        (N'MANUAL_JOB', N'SyncReportServerReports', 4210, N'WarehouseMgmt.SyncReportServerReports'),
        (N'HOURLY_JOB', N'SyncReportServerUserEntries', 4220,N'WarehouseMgmt.SyncReportServerUserEntries'),
        (N'MANUAL_JOB', N'SyncReportServerUserEntries', 4220, N'WarehouseMgmt.SyncReportServerUserEntries'),
        (N'HOURLY_JOB', N'SyncReportServerUsers', 4230,N'WarehouseMgmt.SyncReportServerUsers'),
        (N'MANUAL_JOB', N'SyncReportServerUsers', 4230, N'WarehouseMgmt.SyncReportServerUsers'),
        (N'HOURLY_JOB', N'SyncReportServerFormatEntries', 4240,N'WarehouseMgmt.SyncReportServerFormatEntries'),
        (N'MANUAL_JOB', N'SyncReportServerFormatEntries', 4240, N'WarehouseMgmt.SyncReportServerFormatEntries'),
        (N'HOURLY_JOB', N'SyncReportServerReportFormat', 4250,N'WarehouseMgmt.SyncReportServerReportFormat'),
        (N'MANUAL_JOB', N'SyncReportServerReportFormat', 4250, N'WarehouseMgmt.SyncReportServerReportFormat'),
        (N'HOURLY_JOB', N'StageFactReportServerExecutionLog', 4260, N'WarehouseStaging.StageFactReportServerExecutionLog'),
        (N'MANUAL_JOB', N'StageFactReportServerExecutionLog', 4260, N'WarehouseStaging.StageFactReportServerExecutionLog'),
        (N'HOURLY_JOB', N'SyncFactReportServerExecutionLog', 4270, N'WarehouseMgmt.SyncFactReportServerExecutionLog'),
        (N'MANUAL_JOB', N'SyncFactReportServerExecutionLog', 4270, N'WarehouseMgmt.SyncFactReportServerExecutionLog')
) AS v ([JobId],[StepName],[StepNo],[ExecName])
    ON v.JobID = js.JobID
    AND v.StepName = js.StepName
WHEN MATCHED THEN 
    UPDATE
    SET StepNo = v.StepNo,
        ExecName = v.ExecName
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (JobId, StepName, StepNo, ExecName)
    VALUES (v.JobId, v.StepName, v.StepNo, v.ExecName);

然后对于第二个语句,为了清楚起见,我会用一个通用的 table 表达式封装新数据,但原理是相同的(虽然我不确定例如你想要匹配的列或更新):

WITH NewSyncJobStep AS
(   SELECT  JobStepId = JS.Id,
            StepType = 'SQL',
            SyncDataSQLId = SSD.Id
    FROM    WarehouseMgmt.JobSteps JS
            JOIN 
            (
                VALUES
                    ('SyncReportServerReports',  'WarehouseMgmt.DimReportServerReports'),
                    ('SyncReportServerUserEntries',  'WarehouseMgmt.DimReportServerUserEntries'),
                    ('SyncReportServerUsers',  'WarehouseMgmt.DimReportServerUsers'),
                    ('SyncReportServerFormatEntries',  'WarehouseMgmt.DimReportServerFormatEntries'),
                    ('SyncReportServerReportFormat',  'WarehouseMgmt.DimReportServerReportFormat'),
                    ('StageFactReportServerExecutionLog',  'WarehouseStaging.FactReportServerExecutionLog'),
                    ('SyncFactReportServerExecutionLog',  'WarehouseMgmt.FactReportServerExecutionLog')

            ) V([SyncJobStep], [SQLDataObjectName])
                ON JS.StepName=V.[SyncJobStep]
            JOIN WarehouseMgmt.SyncSQLData SSD 
                ON V.[SQLDataObjectName]=SSD.ObjectName
)
MERGE WarehouseMgmt.SyncJobSteps AS sjs
USING NewSyncJobStep AS n
    ON n.JobStepId = sjs.JobStepId
WHEN MATCHED THEN 
    UPDATE SET SyncDataSQLId = n.SyncDataSQLId
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (JobStepId, StepType, SyncDataSQLId)
    VALUES (n.JobStepId, n.StepType, n.SyncDataSQLId);