У меня есть простая таблица базы данных (SQL Server 2008 R2 Express), которая имеет следующее определение:
ID INT Auto Inc, PK
Name VARCHAR(64) Unique Key
Telephone VARCHAR(128)
У меня есть хранимая процедура, которую я выполняю для обновления записей в таблице, которая в основном делает следующее:
UPDATE customers
SET Name = @name, Telephone = @Telephone
WHERE id = @id
В настоящее время у меня есть две записи в таблице
ID Name Telephone
1 Fred 01234 567890
2 John 09876 543210
Когда я вызываю свою хранимую процедуру для обновления номера телефона для Джона, SQL, который эффективно выполняется,
UPDATE customers
SET Name = 'John', Telephone = '02468 135790'
WHERE id = 2
Это генерирует нарушение UNIQUE KEY в поле Name
. Теперь, когда поле Name фактически не изменяется, почему это происходит?
Поскольку все действия с базой данных обрабатываются моим приложением с помощью хранимых процедур, я мог бы исправить это, удалив ограничение и изменив хранимые процедуры для принудительного применения ограничения вручную, но это просто кажется неправильным.
Учитывая, что в моей таблице на самом деле много других полей, должна быть общая работа, которую я могу использовать для предотвращения этих проблем с ложными ограничениями, без необходимости генерировать многочисленные хранимые процедуры для обновления определенных полей?
Изменить: приведенная выше таблица была упрощена, чтобы вопрос был более управляемым, я уверен, что я не пропустил ничего важного, но для информации фактическое определение таблицы выглядит следующим образом
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
... и хранимая процедура
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