SQL Server / TSQL Обновление таблицы с уникальным ограничением - PullRequest
0 голосов
/ 08 июля 2010

Если у меня две таблицы, скажем:

Clients
(
  ClientID int primary key,
  ClientName varchar(50) not null
)

и

Addresses
(
  AddressID int primary key,
  AddressLine1 varchar(50),
  etc..
  ClientID int not null,
  IsPrimaryAddress bit not null
)

с уникальным ограничением по (ClientID, IsPrimaryAddress), как можно обновлять эти таблицы из коллекции в коде(ни одного оператора SQL) без нарушения ограничения?

Спасибо ...

Ответы [ 2 ]

2 голосов
/ 08 июля 2010

Вероятно, ошибочно иметь уникальное ограничение (ClientID, IsPrimaryAddress), если только вы не хотите убедиться, что у клиента может быть не более двух адресов (один основной, один другой), как всякий раз, когда вы пытаетесь добавить дальшенеосновные адреса вы будете нарушать ограничение целостности.

1 голос
/ 08 июля 2010

Как уже упоминали другие, проблема здесь, похоже, связана с чрезмерно ограничительным уникальным ограничением.Предположительно это вызывает трудности, когда у вас есть два адреса для клиента и вы хотите поменять местами основной.В этом случае вы сначала обновите первичный адрес, чтобы он был неосновным, и сразу же выйдете из строя, поскольку два неосновных адреса для одного и того же клиента нарушают ограничение.

Таким образом, проблема будет решена путем принудительного примененияуникальное ограничение на ClientID, когда адрес является основным.Такие условные уникальные ограничения уже обсуждались при переполнении стека.

Если вы использовали Oracle, вы можете быть умным и сделать что-то вроде этого:

CREATE UNIQUE INDEX unique_primary_addr ON Addresses (
  DECODE (IsPrimaryAddress, 1, ClientId, NULL));

Но я предполагаю, что вы используете sql-сервер или что-то еще, поэтому вы будете вынуждены сделать что-то вроде этого:

CREATE FUNCTION PrimaryAddressCount(@Id INT) RETURNS INT AS
BEGIN
  DECLARE @ret INT;
  SELECT @ret = COUNT(*) FROM Addresses WHERE ClientId = @Id AND IsPrimaryAddress = 1;
  RETURN @ret;
END;
GO

ALTER TABLE Addresses
  ADD CONSTRAINT SinglePrimaryConstraint
CHECK (IsPrimaryAddress != 1 OR dbo.PrimaryAddressCount(ClientId) = 1);

В любом случае, результирующее ограничение разрешит столько неосновныхАдреса, которые вам нравятся для каждого клиента, но будут использовать один основной адрес.Это должно позволить вам легко обновлять адреса, если вы всегда пишете новый первичный адрес последним.

...