SQL Merge实现数据同步

实例如下:

USE [LVDU_MDM]
GO
/****** Object:  StoredProcedure [dbo].[SyncRole]    Script Date: 2018/7/6 13:59:16 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:        Adolph.Chen
-- Create date: 2018-07-06
-- Description:    从BPM同步角色和人员角色关系信息
-- SELECT * FROM [dbo].[Log_ServiceLog] WHERE ServiceCode='SyncRole' ORDER BY InvokeTime DESC
-- EXEC [dbo].[SyncRole] 1,1
-- =============================================
AlTER PROCEDURE [dbo].[SyncRole]
    @SyncRole INT--同步角色:1代表同步,0代表不同步
    ,@SyncUserRole INT--同步人员角色关系:1代表同步,0代表不同步
AS
BEGIN
    BEGIN TRY
    IF(@SyncRole=1)
    BEGIN
        PRINT '同步角色START'
        INSERT INTO [dbo].[Log_ServiceLog](ServiceLogID,AppID,ServiceCode,InvokeTime,Result,ExceptionMsg)
        VALUES(NEWID(),1,'SyncRole',GETDATE(),1,'同步角色START');
        --获取数据
        SELECT * INTO #Temp_Role FROM [LVDU_BPM].[dbo].[V_Guest_GetUserRoleStatus]
        SELECT 
        '' AS RoleType
        ,o.OrganizationCode+'-'+o.RoleCode AS RoleCode
        ,o.OrganizationName+'-'+o.RoleName AS RoleName
        ,NULL AS Description
        ,1 AS Status
        ,NULL AS CreateUserID
        ,GETDATE() AS CreateDate
        ,NULL AS ModifyUserID
        ,NULL AS ModifyDate
        INTO #Temp_RoleInfo
        FROM #Temp_Role o
        group by o.OrganizationCode,o.RoleCode,o.OrganizationName,o.RoleName        
        --导入数据
        MERGE INTO [dbo].[SYS_Role] AS T  
        USING #Temp_RoleInfo AS S  
        ON T.RoleCode=S.RoleCode
        WHEN MATCHED--源数据、目标数据同时存在,更新  
        THEN UPDATE SET 
            T.RoleName=S.RoleName
        WHEN NOT MATCHED--目标数据不存在,插入  
        THEN INSERT VALUES(
           S.RoleType
          ,S.RoleCode
          ,S.RoleName
          ,S.Description
          ,S.Status
          ,S.CreateUserID
          ,S.CreateDate
          ,S.ModifyUserID
          ,S.ModifyDate
        )
        WHEN NOT MATCHED BY SOURCE AND T.RoleID<>1 --源数据不存在,删除        
        THEN UPDATE SET T.Status=0;
        DROP TABLE #Temp_RoleInfo
        DROP TABLE #Temp_Role
        PRINT '同步角色END'
        INSERT INTO [dbo].[Log_ServiceLog](ServiceLogID,AppID,ServiceCode,InvokeTime,Result,ExceptionMsg)
        VALUES(NEWID(),1,'SyncRole',GETDATE(),1,'同步角色END');
    END
    IF(@SyncUserRole=1)
    BEGIN
        PRINT '同步人员角色关系START'
        INSERT INTO [dbo].[Log_ServiceLog](ServiceLogID,AppID,ServiceCode,InvokeTime,Result,ExceptionMsg)
        VALUES(NEWID(),1,'SyncRole',GETDATE(),1,'同步人员角色关系START');
        --获取数据
        SELECT *,OrganizationCode+'-'+RoleCode AS Code INTO #Temp_UserRole FROM [LVDU_BPM].[dbo].[V_Guest_GetUserRoleStatus]
        SELECT 
        u.UserID AS UserID
        ,r.RoleID AS RoleID
        INTO #Temp_UserRoleInfo
        FROM #Temp_UserRole o
        inner JOIN [dbo].[MDM_User] u on u.UserLoginID = o.UserAccount
        inner JOIN [dbo].[SYS_Role] r on r.RoleCode = o.Code
        --导入数据
        MERGE INTO [dbo].[SYS_UserRole] AS T  
        USING #Temp_UserRoleInfo AS S  
        ON T.UserID=S.UserID AND T.RoleID=S.RoleID
        WHEN NOT MATCHED--目标数据不存在,插入  
        THEN INSERT VALUES(
           S.UserID
          ,S.RoleID
        )  
        WHEN NOT MATCHED BY SOURCE AND T.RoleID<>1--源数据不存在,删除        
        THEN DELETE;
        DROP TABLE #Temp_UserRoleInfo
        DROP TABLE #Temp_UserRole
        PRINT '同步人员角色关系END'
        INSERT INTO [dbo].[Log_ServiceLog](ServiceLogID,AppID,ServiceCode,InvokeTime,Result,ExceptionMsg)
        VALUES(NEWID(),1,'SyncRole',GETDATE(),1,'同步人员角色关系END');
    END
    END TRY
    BEGIN CATCH  -- 捕获异常
    PRINT ERROR_MESSAGE()
    INSERT INTO [dbo].[Log_ServiceLog](ServiceLogID,AppID,ServiceCode,InvokeTime,Result,ExceptionMsg)
    VALUES(NEWID(),1,'SyncRole',GETDATE(),1,ERROR_MESSAGE());
    END CATCH
END

一点小心得:

当你只需要更新目标表部分数据的时候,在MERGE INTO [A] USING [B] ON 后面加where条件是木有用处的

需要在WHEN MATCHED等这种后面加AND条件来过滤数据源中不想被操作到的数据

猜你喜欢

转载自www.cnblogs.com/cn2018/p/9274171.html