Sql 在多个IF不存在的情况下使用Merge语句

Sql 在多个IF不存在的情况下使用Merge语句,sql,sql-server,Sql,Sql Server,我有以下存储过程,它使用多个(如果不存在)条件 Create procedure AuditLogProcDetails (@Id int, @LogId int, @LogDescription varchar(2000), @LogStartDate datetime , @LogEndDate datetime , @Task varchar(100) ) as BE

我有以下存储过程,它使用多个
(如果不存在)条件

Create procedure AuditLogProcDetails
(@Id                 int,
 @LogId          int,
 @LogDescription varchar(2000),
 @LogStartDate   datetime     ,
 @LogEndDate     datetime     ,
 @Task               varchar(100)   
)
as 
BEGIN
  IF NOT EXISTS (SELECT * FROM dbo.AuditLogging where LogId = @LogId and Task = @Task )
    begin
      INSERT INTO dbo.AuditLogging( Id, LogId, Task, LogDescription, StartTime       , EndTime)
                             VALUES (@Id,@LogId,@Task,@LogDescription,@LogStartDate, @LogStartDate)
    end
  ELSE
    begin
      UPDATE dbo.AuditLogging
         SET LogDescription = @LogDescription,
             StartTime = @LogStartDate,
             EndTime=    @LogEndDate 
       WHERE ProcessId = @LogId
         AND Task      = @Task

    end
  -- COMMIT;

    IF NOT EXISTS (SELECT * FROM dbo.AuditLogging where LogId = @LogId and Task = 'INPROGRESS' )
        DECLARE @SetStartTimeInProgress datetime;
        DECLARE @TotalCount int;
    begin

        SET @SetStartTimeInProgress = GETDATE();
      UPDATE dbo.AuditLogging
         SET StartTime = @LogStartDate,
             EndTime=    @LogEndDate 
       WHERE LogId = @LogId
         AND Task      = 'INPROGRESS'        
    end

    IF NOT EXISTS (SELECT * FROM dbo.AuditLogging where LogId = @LogId and Task = 'COMPLETED' )
        DECLARE @SetStartTimeCompleted datetime;
        DECLARE @TotalCount int;
    begin

        SET @SetStartTimeCompleted = LastRunStartDate FROM LogTable  WHERE LogId=@LogId and Status='COMPLETED';
      UPDATE dbo.AuditLogging
         SET StartTime = @SetStartTimeCompleted,
             TOtalCount=    @TotalCount 
       WHERE LogId = @LogId
         AND Task      = 'COMPLETED'         
    end

END

我如何重构上述存储的过程代码,并使用更有效的MERGE语句代替(如果不存在的话)

我认为您可以简单地做到这一点:

CREATE PROCEDURE AuditLogProcDetails
(
    @Id             int,
    @LogId          int,
    @LogDescription varchar(2000),
    @LogStartDate   datetime,
    @LogEndDate     datetime,
    @Task           varchar(100)   
)
AS
BEGIN
  IF NOT EXISTS 
  (
      SELECT * 
      FROM dbo.AuditLogging 
      WHERE LogId = @LogId 
      AND Task = @Task 
  )
  BEGIN
      INSERT INTO dbo.AuditLogging(Id, LogId, Task, LogDescription, StartTime, EndTime)
      VALUES (@Id, @LogId, @Task, @LogDescription, @LogStartDate, @LogStartDate)
  END
  ELSE
  BEGIN
      UPDATE dbo.AuditLogging
      SET    LogDescription = @LogDescription,
             StartTime = @LogStartDate,
             EndTime=    @LogEndDate 
      WHERE  ProcessId = @LogId
      AND    Task      = @Task

  END

  DECLARE @SetStartTimeInProgress datetime;
  DECLARE @TotalCount int;

  SET @SetStartTimeInProgress = GETDATE();

  UPDATE dbo.AuditLogging
  SET StartTime = @LogStartDate,
      EndTime   = @LogEndDate 
  WHERE LogId   = @LogId
  AND Task = 'INPROGRESS'        

  SELECT @SetStartTimeCompleted = LastRunStartDate 
  FROM LogTable  
  WHERE LogId = @LogId 
  AND [Status]  = 'COMPLETED';

  UPDATE dbo.AuditLogging
  SET StartTime  = @SetStartTimeCompleted,
      TOtalCount = @TotalCount 
  WHERE LogId = @LogId
  AND Task    = 'COMPLETED'            
END

MERGE
不是“更有效”。这只是一套不同的代码。在这三条语句中,可能只值得用
merge
替换第一次插入/更新。另外两个你可以删除
IF EXISTS
,因为如果记录不存在,
update
不会做任何事情。我想你可以声明一些变量。例如,声明inprogress int,然后从dbo.AuditLogging中设置inprogress=SELECT count(*),其中LogId=@LogId和Task='inprogress'。最后,检查inprogress>0。只是建议一下,我的朋友!是否可以在更新查询中同时使用Merge和CASE?对于第二个和第三个
if
语句,如果
begin
语句位于错误的位置。由于它们不直接跟在
begin
语句后面,因此它们只控制它们后面的第一行。嗨,Zohar Peled,谢谢,我可以删除第二个和第三个If中的begin语句吗?可以吗?很乐意帮忙:-)