Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 2,1,1) 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--这应该失败 更新[CheckConstraintTest]--此操作应失败 设置ContactType=1_Sql_Sql Server 2000_Constraints - Fatal编程技术网

Sql 2,1,1) 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--这应该失败 更新[CheckConstraintTest]--此操作应失败 设置ContactType=1

Sql 2,1,1) 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--这应该失败 更新[CheckConstraintTest]--此操作应失败 设置ContactType=1,sql,sql-server-2000,constraints,Sql,Sql Server 2000,Constraints,2,1,1) 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--这应该失败 更新[CheckConstraintTest]--此操作应失败 设置ContactType=1 其中CustomerId=1,ContactId=2 更新[CheckConstraintTest]--这应该可以工作 设置ContactType=2 其中CustomerId=1,ContactId=1 插入[CheckConstraint

2,1,1) 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--这应该失败 更新[CheckConstraintTest]--此操作应失败 设置ContactType=1 其中CustomerId=1,ContactId=2 更新[CheckConstraintTest]--这应该可以工作 设置ContactType=2 其中CustomerId=1,ContactId=1 插入[CheckConstraintTest](CustomerId、ContactId、ContactType) 值(1,5,1)--现在应该可以工作了,因为我们在前面的语句中将Cust 1,Contact 1更改为“secondary”
不要对此使用检查约束。您可以在索引视图上使用唯一索引(尽管在2000年,您可能需要做更多的工作,以确保连接使用的
SET
选项与这些选项兼容)@MartinSmith:不需要索引视图。常规的部分索引就足够了:
在作业所有者(jpsid)上创建唯一索引idx\u active\u jpsid,其中isActive=1
,但我认为部分索引只在2008年和2008年可用later@a_horse_with_no_name2008年及以后,问题被标记2000@MartinSmith:是的,我知道它的标签是2000,但是索引视图不是在2000年也不可用吗?@a_horse_with_no_name-索引视图在2000年可用。只是设置选项的要求有点繁琐(arithabort需要启用)哈,至少我没有在一些基本的问题上失去理智。非常感谢你的帮助,亚伦。我将尝试一下您的解决方法和连接项中的解决方法,看看结果如何。如果两个并发连接进行更新,这似乎有一个竞争条件。@Martin是的,您可能可以通过事务更好地保护它。Aaron,考虑到您的凭据(感谢您知道“twofer”是什么,因为我有加拿大亲戚,哈哈)我想知道你对我的答案的看法,以及你是否同意我的“编辑”和警告,还是仍然认为我应该删除我的答案。毕竟,正如马丁指出的(你也同意),即使你的答案也有可能引发“问题”。我喜欢过滤后的索引(由上面有“无”名称的“马”建议),但这需要额外的IO和存储来维护索引,并且仍然可能导致插入/更新失败。如果我的答案有我没有想到的危险,就尽量不要成为一个“得分猎犬”
CREATE TABLE JobOwners
(
    LogID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
    JPSID int NOT NULL FOREIGN KEY REFERENCES JobsPerShift(JPSID),
    EmpID int NOT NULL FOREIGN KEY REFERENCES Employees(EmpID),
    DateStarted datetime,
    DateEnded datetime,
    IsActive tinyint NOT NULL   
)
CREATE FUNCTION CheckActiveCount(@JPSID INT) 
RETURNS INT AS 
BEGIN
    DECLARE @result INT
    SELECT @result = COUNT(*) FROM JobOwners WHERE JPSID = @JPSID AND IsActive = 1
    RETURN @result
END
GO

ALTER TABLE JobOwners 
 ADD CONSTRAINT CK_JobOwners_IsActive
 CHECK ((IsActive = 1 AND dbo.CheckActiveCount(JPSID) <= 1) OR (IsActive = 0))
INSERT INTO JobOwners
 VALUES(2,2,NULL,NULL,1)

(1 row(s) affected)

INSERT INTO JobOwners
 VALUES(2,2,NULL,NULL,0)

(1 row(s) affected)

INSERT INTO JobOwners
 VALUES(2,3,NULL,NULL,1)

INSERT statement conflicted with COLUMN FOREIGN KEY constraint...
UPDATE JobOwners SET IsActive = 1
 WHERE LogID = 3

(1 row(s) affected)
CREATE TRIGGER dbo.CheckJobOwners ON dbo.JobOwners
INSTEAD OF UPDATE
AS
BEGIN
  SET NOCOUNT ON;
  BEGIN TRANSACTION;

  UPDATE j SET IsActive = 1 -- /* , other columns */
    FROM dbo.JobOwners AS j INNER JOIN inserted AS i
    ON i.LogID = j.LogID
    WHERE i.IsActive = 1 AND NOT EXISTS 
    (    -- since only one can be active, we don't need an expensive count:
      SELECT 1 FROM dbo.JobOwners AS j2
        WHERE j2.JPSID = i.JPSID
        AND j2.IsActive = 1 AND j2.LogID <> i.LogID
    )
    AND NOT EXISTS 
    (    -- also need to protect against two rows updated by same statement: 
      SELECT 1 FROM inserted AS i2
        WHERE i2.JPSID = i.JPSID
        AND i2.IsActive = 1 AND i2.LogID <> i.LogID
    );

  -- *if* you want to report errors:
  IF (@@ROWCOUNT <> (SELECT COUNT(*) FROM inserted WHERE IsActive = 1))
    RAISERROR('At least one row was not updated.', 11, 1);

  -- assume setting active = 0 always ok & that IsActive is not nullable
  UPDATE j SET IsActive = 0 -- /* , other columns */
    FROM dbo.JobOwners AS j INNER JOIN inserted AS i
    ON j.LogID = i.LogID
    WHERE i.IsActive = 0;

  COMMIT TRANSACTION;
END
GO
CREATE TABLE [dbo].[CheckConstraintTest](
    [CustomerId] [int] NOT NULL,
    [ContactId] [int] NOT NULL,
    [ContactType] [int] NULL,
CONSTRAINT [PK_CheckConstraintTest] PRIMARY KEY CLUSTERED (
    [CustomerId] ASC,
    [ContactId] ASC
))
GO

CREATE FUNCTION dbo.OnlyOnePrimaryContact (
    @CustId int, @ContactType int ) RETURNS bit
AS BEGIN
    DECLARE @result bit, @count int
    SET @ContactType = 1 --only care about "1" but needed parm to force SQL to "care" about that column
    SELECT @count = COUNT(*) FROM CheckConstraintTest WHERE [CustomerId] = @CustId AND [ContactType] = @ContactType
    IF @count < 2 SET @result = 1
    ELSE  SET @result = 0
    RETURN @result
END
GO

ALTER TABLE [dbo].[CheckConstraintTest] WITH CHECK ADD CONSTRAINT [SinglePrimaryContact] CHECK  (([dbo].[OnlyOnePrimaryContact]([CustomerId],[ContactType])=(1)))
GO

ALTER TABLE [dbo].[CheckConstraintTest] CHECK CONSTRAINT [SinglePrimaryContact]
GO

INSERT INTO [CheckConstraintTest] (CustomerId, ContactId, ContactType) 
VALUES (1,1,1), (1,2,2), (1,3,2), (1,4,2), (2,1,1)

INSERT INTO [CheckConstraintTest] (CustomerId, ContactId, ContactType) 
VALUES (1,5,1) --This should fail

UPDATE [CheckConstraintTest] --This should fail
SET ContactType = 1
WHERE CustomerId = 1 AND ContactId = 2

UPDATE [CheckConstraintTest] --This should work
SET ContactType = 2
WHERE CustomerId = 1 AND ContactId = 1

INSERT INTO [CheckConstraintTest] (CustomerId, ContactId, ContactType) 
VALUES (1,5,1) --This should work now since we change Cust 1, Contact 1, to "secondary" in previous statement