[英]SQL Server / TSQL Updating a table with a unique constraint
如果我有两个表,请说:
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语句)中的那些表?
谢谢...
跨(ClientID,IsPrimaryAddress)具有唯一约束可能是一个错误,除非您想确保一个客户端最多可以拥有两个地址(一个主地址,一个其他地址),因为您每次尝试添加其他非主地址时解决您将违反完整性约束的问题。
正如其他人已经提到的那样,这里的问题似乎源于过于严格的唯一约束。 据推测,这在您有两个客户端地址并希望交换哪个是主要地址时会造成困难。 在这种情况下,您首先将主地址更新为非主地址,然后立即失败,因为同一客户端的两个非主地址违反了约束。
因此,仅当地址为主要地址时,才对ClientID强制执行唯一性约束即可解决此问题。 之前已经在堆栈溢出中讨论了这种条件唯一约束 。
如果您使用的是Oracle,那么您可以很聪明,并执行以下操作:
CREATE UNIQUE INDEX unique_primary_addr ON Addresses (
DECODE (IsPrimaryAddress, 1, ClientId, NULL));
但是我假设您正在使用sql-server或其他工具,因此您将被迫执行以下操作:
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);
无论哪种方式,结果约束都将允许您为每个客户端使用任意数量的非主要地址,但将强制使用一个主要地址。 只要您总是最后写入新的主地址,这就能使您轻松地更新地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.