合并表与更新ms sql

时间:2015-01-06 12:01:27

标签: sql sql-server merge

我在sql中使用merge进行一次更新插入需要帮助 这是原始的插入

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,因为数据库中已有值,我不想删除它们。如何在我的第一个Insert和4 new中更新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] ;

为什么这是错的?

1 个答案:

答案 0 :(得分:1)

您可以在merge语句中使用表值构造函数作为源表,其方式与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);

然后对于第二个语句,为了清楚起见,我将使用公共表表达式封装新数据,但原理是相同的(尽管我不确定您想要匹配或更新哪些列):

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);