Нарушаване на ограничението UNIQUE KEY по време на актуализация на SQL

Имам проста таблица на база данни (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

Това генерира нарушение на УНИКАЛЕН КЛЮЧ в полето 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

person Bryan    schedule 30.08.2011    source източник
comment
Това определено не звучи правилно. Сигурни ли сте, че всъщност няма дубликат и че уникалното ограничение е било активирано преди това без опцията WITH CHECK, която би потвърдила съществуващите данни? Или имате някакви причини, които може да причиняват това?   -  person Martin Smith    schedule 31.08.2011
comment
@Martin: 100% положителен, няма дубликат, но не съм запознат с опцията WITH CHECK, ако трябва да съм честен.   -  person Bryan    schedule 31.08.2011
comment
Имате ли тригер или нещо друго, което влияе върху актуализацията?   -  person JNappi    schedule 31.08.2011
comment
@Bryan - Всъщност не съм 100% сигурен дали се отнася за уникални ограничения или просто проверява ограничения и FK, но ако нямате никакви дупки, тогава не може да е така. Какво ще кажете за тригерите?   -  person Martin Smith    schedule 31.08.2011
comment
Никъде не виждам тригери. Наследих тази празна структура на база данни, която AFAIK е просто поредица от таблици и релации.   -  person Bryan    schedule 31.08.2011
comment
@Bryan - Можете ли да публикувате действителния си код на съхранена процедура?   -  person Martin Smith    schedule 31.08.2011
comment
Актуализирах въпроса, за да дам пълната SQL дефиниция на таблицата, само в случай, че съм пропуснал нещо критично от моята първоначална опростена версия на въпроса.   -  person Bryan    schedule 31.08.2011
comment
@Bryan: Липсва ви WHERE във вашия израз UPDATE, така че в момента ще се опита да актуализира всички редове.   -  person Martin Smith    schedule 31.08.2011
comment
О Боже! Не мога да повярвам, че съм го пропуснал! Мисля, че е време да приключим вечерта. Моля, публикувайте като отговор Мартин и аз ще приема (и ще претърпя неудобството да оставя този въпрос отворен за всички).   -  person Bryan    schedule 31.08.2011
comment
Вероятно е добре, че имате уникално ограничение за името.. в противен случай цялата маса щеше да бъде изпразнена.   -  person NotMe    schedule 31.08.2011
comment
@Bryan - Случва се на всички ни в даден момент!   -  person Martin Smith    schedule 31.08.2011


Отговори (1)


Липсва ви WHERE във вашия израз UPDATE, така че в момента ще се опита да актуализира всички редове в таблицата със същите стойности.

person Martin Smith    schedule 30.08.2011
comment
Случва се дори и на най-добрите от нас. Как бих могъл да знам това, питате вие? :) - person Adriano Carneiro; 31.08.2011