dbaSQL
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
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
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
i'm not certain... let me review just a bit, back shortly
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?
any thoughts at all?
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
oh crap
ASKER
very embarrassed, but very grateful for the direction, lowfat
that was it
that was it
Why not just use an identity column as your identifier, and sidestep this issue?
Regards,
Patrick