Reputation: 117
This is my DDL:
CREATE TABLE dbo.KeyName
(
KeyNameID INT NOT NULL IDENTITY(1,1),
PartName VARCHAR(20) NOT NULL ,
RwVersion ROWVERSION NOT NULL
CONSTRAINT PK_KeyName PRIMARY KEY CLUSTERED (KeyNameID)
);
This is my stored procedure:
ALTER PROCEDURE [dbo].[uspKeyNameUpdate]
@KeyNameID INT,
@PartName VARCHAR(20),
@RwVersion BIGINT
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
BEGIN
DECLARE @newId INT = 0
INSERT INTO dbo.KeyName(PartName) VALUES(@PartName)
SELECT @PartName AS PartName
WHERE NOT EXISTS (
SELECT PartName FROM dbo.KeyName WHERE PartName = @PartName)
SET @newId = SCOPE_IDENTITY()
IF ISNULL(@newId,0) != 0
INSERT INTO dbo.EmployeeName(KeyNameID,EmployeeID) VALUES(@newId,@KeyNameID)
END
The sp works if PartName does not exist in the KeyName table. However when I call it the second time with the same details it fails with the following error:
Cannot insert duplicate key row in object 'dbo.KeyName' with unique index 'UX_KeyName'. The duplicate key value is (winston).
The statement has been terminated.
I replaced the INSERT block with the following:
IF NOT EXISTS(SELECT * FROM KeyName WHERE PartName = @PartName)
INSERT INTO KeyName(PartName) VALUES(@PartName)
SELECT @newId = SCOPE_IDENTITY()
INSERT INTO EmployeeName(KeyNameID,EmployeeID) VALUES(@newId,@KeyNameID)
The same error:
I am at sea currently, please help.
Upvotes: 0
Views: 277
Reputation: 96028
I think the problem is that you think that the statements below are one statement:
INSERT INTO dbo.KeyName(PartName) VALUES(@PartName)
SELECT @PartName AS PartName
WHERE NOT EXISTS (
SELECT PartName FROM dbo.KeyName WHERE PartName = @PartName)
These are not 1 statement, they are two; an INSERT
statement and a SELECT
statement. If we terminate your statements, which you should be doing anyway as not doing so is deprecated, and add some additional formatting perhaps this becomes more clear:
INSERT INTO dbo.KeyName(PartName)
VALUES(@PartName);
SELECT @PartName AS PartName
WHERE NOT EXISTS (SELECT PartName
FROM dbo.KeyName
WHERE PartName = @PartName);
As you can see, as a result the parameter, @PartName
will always be INSERT
ed into your table regardless of if it exists or not.
Likely you actually want something like this:
ALTER PROCEDURE [dbo].[uspKeyNameUpdate] @KeyNameID int,
@PartName varchar(20),
@RwVersion bigint
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM dbo.KeyName WHERE PartName = @PartName)
BEGIN
INSERT INTO dbo.KeyName (PartName)
SELECT @PartName;
INSERT INTO dbo.EmployeeName (KeyNameID,
EmployeeID)
VALUES (SCOPE_IDENTITY(), @KeyNameID);
END;
END;
Upvotes: 6
Reputation: 189
I think you are having trouble with the INSERT-SELECT syntax.
Try removing "VALUES(@PartName)" and it should be fine.
Upvotes: 2