I have a simple database table (SQL Server 2008 R2 Express), which has a definition as follows:
ID INT Auto Inc, PK
Name VARCHAR(64) Unique Key
Telephone VARCHAR(128)
I have a stored procedure which I execute to update records within the table which basically does the following:
UPDATE customers
SET Name = @name, Telephone = @Telephone
WHERE id = @id
Currently, I have two entries in the table
ID Name Telephone
1 Fred 01234 567890
2 John 09876 543210
When I call my stored procedure to update the telephone number for John, the SQL that is effectively executed is
UPDATE customers
SET Name = 'John', Telephone = '02468 135790'
WHERE id = 2
This generates a UNIQUE KEY violation on the Name
field. Now as the Name field doesn't actually change, why does this occur?
As all database actions are being handled by my app using stored procedures, I could fix this by removing the constraint, and modifying the stored procedures to manually enforce the constraint, but this just seems wrong.
Given that my table actually has many more fields, there must be a generic work around that I can employ to prevent these false constraint problems, without having to generate numerous stored procedures to update specific fields?
Edit: The above table was simplified to keep the question more manageable, I'm pretty sure I've not missed anything important, but for info, the actual definition of the table is as follows
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[companies](
[id] [int] IDENTITY(1,1) NOT NULL,
[typeId] [int] NOT NULL,
[name] [varchar](64) NOT NULL,
[displayName] [varchar](128) NOT NULL,
[deliveryAddress] [varchar](1024) NOT NULL,
[invoiceAddress] [varchar](1024) NOT NULL,
[telephone] [varchar](64) NOT NULL,
[fax] [varchar](64) NOT NULL,
[email] [varchar](256) NOT NULL,
[website] [varchar](256) NULL,
[isActive] [bit] NOT NULL,
CONSTRAINT [PK_companies] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [Unique Display Name] UNIQUE NONCLUSTERED
(
[displayName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [Unique Name] UNIQUE NONCLUSTERED
(
[name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[companies] WITH CHECK ADD CONSTRAINT [Company Type] FOREIGN KEY([id])
REFERENCES [dbo].[companyTypes] ([id])
GO
ALTER TABLE [dbo].[companies] CHECK CONSTRAINT [Company Type]
GO
...and the stored procedure
ALTER PROCEDURE UpdateCompany
@id INT,
@typeId INT,
@name VARCHAR(64),
@displayName VARCHAR(128),
@deliveryAddress VARCHAR(1024),
@invoiceAddress VARCHAR(1024),
@telephone VARCHAR(64),
@fax VARCHAR(64),
@email VARCHAR(256),
@website VARCHAR(256),
@isActive BIT
AS
BEGIN
UPDATE companies
SET typeid = @typeid,
name = @name,
displayname = @displayname,
deliveryAddress = @deliveryAddress,
invoiceAddress = @invoiceAddress,
telephone = @telephone,
fax = @fax,
email = @email,
website = @website,
isActive = @isActive
EXEC GetCompany @id
END
GO
You're missing the WHERE
in your UPDATE
statement so currently it will try and update all rows in the table with the same values.