如何定义 "NON-UNIQUE" 约束,在 INSERT 上断言现有值?
How to define a "NON-UNIQUE" constraint, asserting existing values on INSERT?
更新:我现在驳回了这个问题背后的想法,并赞成不同的设计。但是,就目前的问题而言,给出的答案是一个很好的答案。我很高兴地接受了它。
我想在 SQL 服务器中实现与 UNIQUE constraint 相反的东西。
在新行 INSERT
时,必须确保已存在的值之一被重复用于特定列(否则必须创建使用新值的行,请参见下面的注释):
INSERT INTO [dbo].[Item]
(/*...*/
[LogicalId])
VALUES
(/*...*/
123)
GO
如果 LogicalId
的值不在现有值中,这一定会失败。
因为这个值来自 SEQUENCE
,我尝试使用 SEQUENCE
添加一个 CONSTRAINT
子句,如下所示:
ALTER TABLE Item
ADD CONSTRAINT chkInsertNonUniqueLogicalId
CHECK
(
( LogicalId <= (SELECT current_value FROM sys.sequences WHERE name = 'SQ_LogicalId') ) AND
( LogicalId >= (SELECT minimum_value FROM sys.sequences WHERE name = 'SQ_LogicalId') )
);
GO
但这导致了一个错误
Subqueries are not allowed in this context. Only scalar expressions are allowed
如何在使用 INSERT
命令插入新行时断言同一列上的现有值?
注意:应具有新逻辑 ID(尚未使用的值)的行将使用 NULL
进行插入,从而导致具有上述序列的 DEFAULT
约束生效)。这样做的原因是具有数据库控制(而非用户控制)的逻辑 ID。
当您按照自己的方式描述它时,这似乎是一个奇怪的要求,但是,那是因为您从错误的角度看待它。您在这里肯定是外键约束,看来您缺少包含外键的 table。
因此,您需要创建所说的table,然后再创建外键约束。
CREATE TABLE dbo.Logical (LogicalID int NOT NULL
/*,...Other Columns? ...*/ );
ALTER TABLE dbo.Logical ADD CONSTRAINT PK_LogicalID
PRIMARY KEY CLUSTERED (LogicalID);
GO
INSERT INTO dbo.Logical (LogicalID /*,... Other Columns? ...*/)
SELECT DISTINCT LogicalID /*,... Other Columns? ...*/
FROM dbo.Items
WHERE LogicalID IS NOT NULL;
GO
ALTER TABLE dbo.Items ADD CONSTRAINT FK_LogicalID
FOREIGN KEY (LogicalID) REFERENCES dbo.Logical(LogicalID);
更新:我现在驳回了这个问题背后的想法,并赞成不同的设计。但是,就目前的问题而言,给出的答案是一个很好的答案。我很高兴地接受了它。
我想在 SQL 服务器中实现与 UNIQUE constraint 相反的东西。
在新行 INSERT
时,必须确保已存在的值之一被重复用于特定列(否则必须创建使用新值的行,请参见下面的注释):
INSERT INTO [dbo].[Item]
(/*...*/
[LogicalId])
VALUES
(/*...*/
123)
GO
如果 LogicalId
的值不在现有值中,这一定会失败。
因为这个值来自 SEQUENCE
,我尝试使用 SEQUENCE
添加一个 CONSTRAINT
子句,如下所示:
ALTER TABLE Item
ADD CONSTRAINT chkInsertNonUniqueLogicalId
CHECK
(
( LogicalId <= (SELECT current_value FROM sys.sequences WHERE name = 'SQ_LogicalId') ) AND
( LogicalId >= (SELECT minimum_value FROM sys.sequences WHERE name = 'SQ_LogicalId') )
);
GO
但这导致了一个错误
Subqueries are not allowed in this context. Only scalar expressions are allowed
如何在使用 INSERT
命令插入新行时断言同一列上的现有值?
注意:应具有新逻辑 ID(尚未使用的值)的行将使用 NULL
进行插入,从而导致具有上述序列的 DEFAULT
约束生效)。这样做的原因是具有数据库控制(而非用户控制)的逻辑 ID。
当您按照自己的方式描述它时,这似乎是一个奇怪的要求,但是,那是因为您从错误的角度看待它。您在这里肯定是外键约束,看来您缺少包含外键的 table。
因此,您需要创建所说的table,然后再创建外键约束。
CREATE TABLE dbo.Logical (LogicalID int NOT NULL
/*,...Other Columns? ...*/ );
ALTER TABLE dbo.Logical ADD CONSTRAINT PK_LogicalID
PRIMARY KEY CLUSTERED (LogicalID);
GO
INSERT INTO dbo.Logical (LogicalID /*,... Other Columns? ...*/)
SELECT DISTINCT LogicalID /*,... Other Columns? ...*/
FROM dbo.Items
WHERE LogicalID IS NOT NULL;
GO
ALTER TABLE dbo.Items ADD CONSTRAINT FK_LogicalID
FOREIGN KEY (LogicalID) REFERENCES dbo.Logical(LogicalID);