Link to home
Start Free TrialLog in
Avatar of dbaSQL
dbaSQLFlag for United States of America

asked on

UPDATE IF EXISTS, otherwise INSERT

yesterday it came to our attention that our unique id wasn't remaining unique upon insert, and certain orders were being rejected.....

our unique id is based on eventtime,eventtype, orderid
the records themselves were distinctly different, but SQL's little timestamp accuracy problem was causing the eventtimes to round.  thus, becoming consistent w/eventtimes already in the table, and causing duplicate constraint violations.

so.  i changed the proc to do an IF/EXISTS.   if it exists, it should be updated.  otherwise, it should be inserted.

today i'm getting the same violations.  i don't know if it is me, or the app, so i was hoping to confirm whether my logic is flawed.  


CREATE PROCEDURE procname
(
   @EventType char(2),
   @EventTime datetime,
   @gwid int,
   @MessageID varchar(32),
   @OrderID varchar(32),
   @ExchangeID varchar(32),
   @EndPoint varchar(8),
   @UserId varchar(16),
   @AcctId varchar(16),
   @Client varchar(32),
   @Symbol varchar(16),
   @Price decimal(18,8),
   @Side char(1),
   @Quantity bigint,
   @OrderMarking char(2),
   @FirmPosition bigint,
   @TimeInForce varchar(5),
   @ExecInstruction varchar(10)=NULL
)
AS
SET NOCOUNT ON
DECLARE @error INT

IF EXISTS(SELECT 1 FROM database.dbo.table1 WHERE GWID = @gwid)
BEGIN
      IF EXISTS(SELECT 1 FROM database.dbo.table2 WHERE MessageID = @messageID AND OrderID = @orderID AND EventType = @eventType)
      BEGIN
            UPDATE database.dbo.table2
            SET EventTime = @eventtime,
            Quantity = @quantity
      END
      ELSE
      BEGIN
            INSERT database.dbo.table2 (
            ....all the fields....
            )
            VALUES (
               .....all the @fields.....
            )
            END
            IF @@ERROR = 0 OR @@ROWCOUNT <> 0  -- thus, successfully inserted
                 RETURN 0
END
            -- on failure run this
            INSERT INTO database.dbo.failuretable (.......all the fields...........)
                  VALUES (.........all the @fields..............)

            RAISERROR (' Events failure upon insert.  MessageID is %s.',16,1,@MessageID) WITH LOG

SET NOCOUNT OFF
GO
Avatar of Patrick Matthews
Patrick Matthews
Flag of United States of America image

Hello dbaSQL,

Why not just use an identity column as your identifier, and sidestep this issue?

Regards,

Patrick
Avatar of dbaSQL

ASKER

I was about to say because, in my opinion, that is a useless way of uniquely identifying your data, as it has absolutely nothing to do w/business dataflow, or operational attributes of any kind.  but.  in this particular dataset, maybe that's ok.  

i'm not certain... let me review just a bit, back shortly
Avatar of dbaSQL

ASKER

no, that's not an option.  i need to figure out why the update if exists isn't handling this.  
any thoughts at all?
Avatar of dbaSQL

ASKER

i'm trying to write it right now myself.  it's failing wthis:

Server: Msg 2627, Level 14, State 2, Procedure procname, Line 33
Violation of UNIQUE KEY constraint 'unc name'. Cannot insert duplicate key in object 'tableName'.

but, of course, that record does not actuall exist, it's just doing this because the time is rounding.
i was sure the UPDATE IF EXISTS would get me around this.
but it's not working
ASKER CERTIFIED SOLUTION
Avatar of Lowfatspread
Lowfatspread
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dbaSQL

ASKER

oh crap
Avatar of dbaSQL

ASKER

very embarrassed, but very grateful for the direction, lowfat
that was it