简体   繁体   中英

SQL update or insert based on last record found

Quick background: Process equipment vendor wrote code to update DB with results of process. Data essentially is: (Order #, Result, Qty) except that the Qty is always 1, and when the batch is large, I get a lot of identical records. Vendor software update is not an option. DB update by vendor is done by calling a stored procedure.

What I want to do in the stored procedure, is if the last record for a specific Order # has identical result as the record currently being inserted, then +1 to Qty of last record (and no new record).

In my research, all examples have included the Result as a part of the Where, which would always combine like results, but my order of results is important. If 3 have result X1, 1 has result X2, and another 2 have result X1, then I need 3 records when finished:

Order  Result Qty 
101    X1     3
101    X2     1
101    X1     2

I also looked at using a cursor, but that seems to expect one to look through several records, and I will only be looking at one. CTE or a nested query seem possible, but I'm not clear how to achive.

In this case, I can assume that only one machine is processing 1 order, and updates for that order will have pleanty of time to complete before the next update. But ideally the solution would be atomic and able to deal with overlapping update requests.

What I am working towards, but don't know if it is the best path (@p variables are passed in, @l variables are used to store the last record):

select top(1) @lOrder = OrderCol, 
              @lResult = ResultCol,
              @lCreateDate = CREATEDATE
 from dbo.LOG
 where OrderCol = @pOrder
 order by CREATEDATE desc

-- make sure the record is no more than x min old, and every other passed value matches
if (    @lOrder = @pOrder 
    and @lResult = @pResult
    and @lCreateDate > DATEADD(minute, -7, GETDATE())
    )
     begin

        Update dbo.LOG 
        set [QtyCol] += @pQty
        where @lOrder = OrderCol
          and @lCreateDate = CREATEDATE

     end 
    else
     begin

        INSERT INTO dbo.LOG 
              ([OrderCol], [QtyCol], [ResultCol], CREATEDATE ) 
        VALUES(@pOrder, @pQty, @pResult, GETDATE());

     end

It seems you need to check to see if the update modified rows. If not then insert. In plain language the code says: "Try to update the LOG table if the order matches an order placed within the last 7 minutes. If it doesn't find a match then insert a new row with the CREATEDATE set to the current date."

select top(1) @lOrder = OrderCol, 
              @lResult = ResultCol,
              @lCreateDate = CREATEDATE
 from dbo.LOG
 where OrderCol = @pOrder
 order by CREATEDATE desc;

Update dbo.LOG 
set [QtyCol] += @pQty
where OrderCol = @lOrder
      and ResultCol = @lResult
      and ResultCol = @pResult
       and CREATEDATE >= dateadd(minute, -7, getdate());
if @@rowcount=0
    insert INTO dbo.LOG([OrderCol], [QtyCol], [ResultCol], CREATEDATE ) 
        VALUES(@pOrder, @pQty, @pResult, GETDATE());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM