一个nvarchar(50)的字段,希望约束可能的值:一个要唯一,一个要是奇数。
同样一个nvarchar(50)的字段,希望约束可能的值:一个要唯一,一个要是偶数。
这样的两个字段的约束怎么设置?
------解决思路----------------------
DECLARE @t TABLE(n NVARCHAR(50) UNIQUE CHECK(CAST(n AS int)%2=0))
奇偶相反, 建议用int型,因为你本来就是要存数字 为什么要nvarchar
------解决思路----------------------
CREATE TABLE T391813657(
id int identity,
c1 nvarchar(50) NOT NULL UNIQUE(c1) CHECK (CONVERT(int,RIGHT(c1,1))%2 = 1),
c2 nvarchar(50) NOT NULL UNIQUE(c2) CHECK (CONVERT(int,RIGHT(c2,1))%2 = 0)
)
GO
INSERT T391813657 VALUES('12345','67890')
INSERT T391813657 VALUES('12345','67892')
INSERT T391813657 VALUES('12346','67894')
INSERT T391813657 VALUES('12347','67890')
INSERT T391813657 VALUES('12349','67891')
SELECT * FROM T391813657
(1 行受影响)
消息 2627,级别 14,状态 1,第 8 行
违反了 UNIQUE KEY 约束 'UQ__T391813657__239E4DCF'。不能在对象 'dbo.T391813657' 中插入重复键。
语句已终止。
消息 547,级别 16,状态 0,第 9 行
INSERT 语句与 CHECK 约束"CK__T391813657__c1__24927208"冲突。该冲突发生于数据库"MyTest",表"dbo.T391813657", column 'c1'。
语句已终止。
消息 2627,级别 14,状态 1,第 10 行
违反了 UNIQUE KEY 约束 'UQ__T391813657__22AA2996'。不能在对象 'dbo.T391813657' 中插入重复键。
语句已终止。
消息 547,级别 16,状态 0,第 11 行
INSERT 语句与 CHECK 约束"CK__T391813657__c2__25869641"冲突。该冲突发生于数据库"MyTest",表"dbo.T391813657", column 'c2'。
语句已终止。
id c1 c2
----------- -------------------------------------------------- --------------------------------------------------
1 12345 67890
------解决思路----------------------
用触发器吧
IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE TA
GO
CREATE TABLE TA(
ID INT IDENTITY,
C1 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C1,1))%2 = 1),
C2 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C2,1))%2 = 0)
)
GO
IF OBJECT_ID('TRA') IS NOT NULL
DROP TRIGGER TRA
GO
CREATE TRIGGER TRA
ON TA
AFTER INSERT,UPDATE
AS BEGIN
IF EXISTS(SELECT * FROM TA GROUP BY C1 HAVING COUNT(C1) > 1)
BEGIN
ROLLBACK
RAISERROR('C1数据错误', 16, 1)
RETURN
END
IF EXISTS(SELECT * FROM TA GROUP BY C2 HAVING COUNT(C2) > 1)
BEGIN
ROLLBACK
RAISERROR('C2数据错误', 16, 1)
RETURN
END
END
GO
INSERT TA VALUES(NULL, 90)
INSERT TA VALUES(NULL, 92)
INSERT TA VALUES(1, NULL)
INSERT TA VALUES(3, NULL)
INSERT TA VALUES(NULL, NULL)
GO
SELECT * FROM TA
------解决思路----------------------
或者用视图
IF OBJECT_ID('VA1') IS NOT NULL
DROP VIEW VA1
GO
IF OBJECT_ID('VA2') IS NOT NULL
DROP VIEW VA2
GO
IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE TA
GO
CREATE TABLE TA(
ID INT IDENTITY,
C1 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C1,1))%2 = 1),
C2 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C2,1))%2 = 0)
)
GO
CREATE VIEW DBO.VA1
WITH SCHEMABINDING
AS
SELECT C1 FROM DBO.TA WHERE C1 IS NOT NULL
GO
CREATE VIEW DBO.VA2
WITH SCHEMABINDING
AS
SELECT C2 FROM DBO.TA WHERE C2 IS NOT NULL
GO
CREATE UNIQUE CLUSTERED INDEX UI1 ON DBO.VA1(C1)
CREATE UNIQUE CLUSTERED INDEX UI2 ON DBO.VA2(C2)
GO
INSERT TA VALUES(NULL, 90)
INSERT TA VALUES(NULL, 92)
INSERT TA VALUES(1, NULL)
INSERT TA VALUES(3, NULL)
INSERT TA VALUES(NULL, NULL)
INSERT TA VALUES(5, 2)
GO
------解决思路----------------------
忘了一点,这两个字段都可能有多条记录为NULL,但是一旦有值必须满足上述条件。
如果有这个要求,你要做两个处理了。
一个 check ,一个 unique index 了 。
部分代码借用前面几位高手的
CREATE TABLE TA(
ID INT IDENTITY,
C1 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C1,1))%2 = 1),
C2 NVARCHAR(50) NULL CHECK (CONVERT(INT,RIGHT(C2,1))%2 = 0)
)
GO
create unique index ix_c1 on ta(c1) where c1 is not null
go
create unique index ix_c2 on ta(c1) where c2 is not null
go
insert into TA(C1,C2) values(1,2)
go
insert into TA(C1,C2) values(null,null)
insert into TA(C1,C2) values(null,null)
insert into TA(C1,C2) values(null,null)
go
print '位置1. -- 更新会出错'
update TA set C1 = 2 where ID = 2
print '位置2. -- 更新会出错'
update TA set C2 = 1 where ID = 2
select * from TA
go
drop table TA
go
(1 行受影响)
(1 行受影响)
(1 行受影响)
(1 行受影响)
位置1. -- 更新会出错
消息 547,级别 16,状态 0,第 2 行
UPDATE 语句与 CHECK 约束"CK__TA__C1__165A2CA1"冲突。该冲突发生于数据库"test",表"dbo.TA", column 'C1'。
语句已终止。
位置2. -- 更新会出错
消息 547,级别 16,状态 0,第 4 行
UPDATE 语句与 CHECK 约束"CK__TA__C2__174E50DA"冲突。该冲突发生于数据库"test",表"dbo.TA", column 'C2'。
语句已终止。
ID C1 C2
----------- -------------------------------------------------- --------------------------------------------------
1 1 2
2 NULL NULL
3 NULL NULL
4 NULL NULL
(4 行受影响)