I have a procedure that insert data to table where the data doesn't exists.
right now it's done in two steps :
- check if the data exists already,
- if not, insert it
i want to change it to do INSERT where not exists as proposed in this article it should improve performance. https://devblogs.microsoft.com/azure-sql/the-insert-if-not-exists-challenge-a-solution/
Here are the procedures :
- Current proceudre
ALTER PROCEDURE [dbo].[AddTest_IfInsert]
(
@CorrelationId uniqueidentifier,
@TransactionId BIGINT
)
AS
BEGIN
IF NOT EXISTS (SELECT TOP 1 1 FROM dbo.Test
WHERE [CorrelationId] = @CorrelationId and TransactionId = @TransactionId
)
BEGIN
INSERT INTO dbo.Test
(CorrelationId,TransactionId)
values (@CorrelationId,@TransactionId)
SELECT SCOPE_IDENTITY() AS ResultId
END
ELSE
SELECT 0 AS ResultId
END
- New procedure :
CREATE OR ALTER PROCEDURE [dbo].[AddTest_WhereInsert]
(
@CorrelationId uniqueidentifier,
@TransactionId BIGINT
)
AS
BEGIN
INSERT INTO dbo.Test
(CorrelationId,TransactionId)
select
@CorrelationId,
@TransactionId
from dbo.Test
where not exists (select top 1 1
FROM dbo.Test WITH (NOLOCK)
where CorrelationId = @CorrelationId
AND TransactionId = @TransactionId
)
IF @@ROWCOUNT = 0
BEGIN
SELECT 0 AS ResultId
END
ELSE
BEGIN
SELECT SCOPE_IDENTITY() AS ResultId
END
END
Here is the Test table that i work with :
CREATE TABLE Test
(
Id BIGINT Identity(1,1) ,
CorrelationId uniqueidentifier,
TransactionId BIGINT
)
Here are my problems with the new procedure:
- If i try to run it for the first time on a empty table It doesn't insert any data. only when i insert the first row it starts inserting data. Here is my code :
DECLARE @CorrelationId nvarchar(100) = 'C0E68827-CC46-4A16-BEDE-B3D98D21AFFA'
DECLARE @TransactionId BIGINT = 4
exec [dbo].[AddTest_WhereInsert] @CorrelationId,@TransactionId
then i inserted data :
DECLARE @CorrelationId nvarchar(100) = 'C0E68827-CC46-4A16-BEDE-B3D98D21AFFA'
DECLARE @TransactionId BIGINT = 4
INSERT INTO dbo.Test
(CorrelationId,TransactionId)
values (@CorrelationId,@TransactionId)
and i try to run it again it starts inserting data.
DECLARE @CorrelationId nvarchar(100) = 'D0E68827-CC46-4A16-BEDE-B3D98D21AFFA'
DECLARE @TransactionId BIGINT = 5
exec [dbo].[AddTest_WhereInsert] @CorrelationId,@TransactionId
don't understand why is that?
then i run
DECLARE @CorrelationId nvarchar(100) = 'E0E68827-CC46-4A16-BEDE-B3D98D21AFFA'
DECLARE @TransactionId BIGINT = 8
exec [dbo].[AddTest_WhereInsert] @CorrelationId,@TransactionId
select * from dbo.Test
why does it insert duplicate data? what is wrong with my code?