我试图基于另一个表的值来约束一个表的值。对于T1,列“ col”允许为“ A”或“ B”。对于T2,列“ col”允许为“ C”或“ D”。但是,如果T1.col为“ B”,则不允许T2.col为“ D”。它们具有T1.PK = T2.FK的多对一关系。如果我在加入T1.col ='B'时尝试在D2.col中插入D,它应该会失败。
我看到了this,但我没有尝试做任何聚合函数。我目前的尝试是这样
CREATE FUNCTION dbo.CheckAddition()
RETURNS bit
AS BEGIN RETURN (
SELECT CASE
WHEN T2.col = 'C' THEN 1
WHEN T2.col = 'D' AND T1.col = 'A' THEN 1
ELSE 0
END AS 'Check'
FROM T1
INNER JOIN T2
ON T1.PK = T2.FK
) END
GO;
ALTER TABLE Shift ADD CONSTRAINT checkAdd CHECK (dbo.CheckAddition() = 1);
但是由于它不是合计的,所以出现此故障。
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
编辑
我的整张桌子看起来像这样
CREATE TABLE [dbo].[T1](
[PK] [bigint] IDENTITY(1,1) NOT NULL,
[col] [char](1) NOT NULL,
CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED
(
[PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[T1] WITH CHECK ADD CONSTRAINT [CK_T1] CHECK (([col]='B' OR [col]='A'))
GO
ALTER TABLE [dbo].[T1] CHECK CONSTRAINT [CK_T1]
GO
CREATE TABLE [dbo].[T2](
[PK] [bigint] IDENTITY(1,1) NOT NULL,
[FK] [bigint] NOT NULL,
[col] [char](1) NOT NULL,
CONSTRAINT [PK_T2] PRIMARY KEY CLUSTERED
(
[PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[T2] WITH CHECK ADD CONSTRAINT [FK_T2_T1] FOREIGN KEY([FK])
REFERENCES [dbo].[T1] ([PK])
GO
ALTER TABLE [dbo].[T2] CHECK CONSTRAINT [FK_T2_T1]
GO
ALTER TABLE [dbo].[T2] WITH CHECK ADD CONSTRAINT [CK_T2] CHECK (([col]='D' OR [col]='C'))
GO
ALTER TABLE [dbo].[T2] CHECK CONSTRAINT [CK_T2]
GO
如果T1.col中匹配的PK / FK ='A',我正在尝试使T2.col不能为'D'
答案 0 :(得分:1)
可以解决您遇到的错误
CREATE FUNCTION dbo.CheckAddition()
RETURNS bit
AS BEGIN
DECLARE @Res BIT
SELECT @Res = CASE
WHEN T2.col = 'C' THEN 1
WHEN T2.col = 'D' AND T1.col = 'A' THEN 1
ELSE 0
END
FROM T1
INNER JOIN T2
ON T1.PK = T2.FK
RETURN @Res
END
GO;
ALTER TABLE Shift ADD CONSTRAINT checkAdd CHECK (dbo.CheckAddition() = 1);
但是从性能上考虑,安全性更好。...
CREATE FUNCTION dbo.CheckAddition(@FKValue INT, @Value CHAR(1))
RETURNS bit
AS BEGIN
DECLARE @Res BIT
SELECT @Res = CASE
WHEN @Value = 'D' AND T1.Col = 'B' THEN 0
ELSE 1
END
FROM T1
WHERE T1.FK = @FKValue
RETURN @Res
END
GO;
ALTER TABLE T2 ADD CONSTRAINT checkValue CHECK (Col IN ('C','D'));
ALTER TABLE T2 ADD CONSTRAINT checkAdd CHECK (dbo.CheckAddition(FK, Col) = 1);
该检查在插入值之前运行,因此,如果函数检查提交的值,则在设置错误的值时不会返回错误,但是在尝试将其更改为有效值时会返回错误。 。 这样,您可以发送要验证的值,然后再插入...
答案 1 :(得分:0)
使用@HasanMahmood的建议,此方法有效。
MyModel.architect