我在SQL-Server
2008 R2中设计了表格。
我在该表中有一个列,在插入数据时需要对另一个表进行检查。
ALTER TABLE Table1
WITH CHECK ADD CONSTRAINT CK_Code
CHECK (MyField in (Select Field From Table2))
这会导致错误
在此上下文中不允许子查询。只允许使用标量表达式。
我已经查看过有关Check Constraint - Subqueries are not allowed in this context的问题。
有没有办法在不使用触发器的情况下实现这一目标?
答案 0 :(得分:43)
注意,您真正想要的是外键约束。也就是说,要在检查中获得“查询”,您可以编写包含查询的函数并输出标量值,然后在检查约束中使用该函数。
CREATE FUNCTION myFunction (
@field DATATYPE(?)
)
RETURNS VARCHAR(5)
AS
BEGIN
IF EXISTS (SELECT* FROM Table2 WHERE MYFIELD = @field)
return 'True'
return 'False'
END
这样的事情。未经测试。
然后您可以将其添加到支票中
ALTER TABLE Table1
WITH CHECK ADD CONSTRAINT CK_Code
CHECK (myFunction(MYFIELD) = 'True')
答案 1 :(得分:7)
您不能在检查约束内部进行子查询。你可以做的是使用一个UDF,它返回一个检查约束内的标量值。
第1步:创建表
USE CTBX
GO
CREATE TABLE RawMaterialByGender
(
RMGID int primary key identity(1,1),
RMID smallint foreign key references RawMaterialMaster(RMID),
LeveLMasterID smallint foreign key references LevelMaster(LevelTextID),
IsDeleted bit
)
步骤2:创建返回标量的UDF
Create FUNCTION [dbo].[IsValidLevelMasterGender](@LevelMasterID smallint)
RETURNS bit
AS
BEGIN
DECLARE @count smallint;
DECLARE @return bit;
SELECT @count = count(LevelTextID)
FROM [LevelMaster]
WHERE LevelCategoryID = 3 AND IsActive = 1 AND LevelTextID=@LevelMasterID
IF(@count = 0)
SET @return = 'false';
ELSE
SET @return = 'true';
RETURN @return;
END;
GO
步骤3:更改表以添加CHECK约束
ALTER TABLE RawMaterialByGender
ADD CONSTRAINT check_LevelMasterID CHECK (dbo.IsValidLevelMasterGender(LeveLMasterID) = 'true')
答案 2 :(得分:3)
ALTER TABLE Table1
ADD CONSTRAINT FK_Table1_Code FOREIGN KEY (MyField)
REFERENCES Table2 (Field) ;
参考:http://msdn.microsoft.com/en-us/library/ms190273.aspx
注意:我没有检查上面的语法。
答案 3 :(得分:0)
首先,在您的示例中,您显然需要FK约束。
另一个可能性是使用WITH CHECK OPTION
视图并通过它访问用户:
CREATE TABLE Table1(i INT PRIMARY KEY, CK_Code CHAR(1));
CREATE TABLE Table2(Field CHAR(1));
INSERT INTO Table2(Field) VALUES ('A'),('B'), ('C');
GO
CREATE VIEW v_Table1
AS
SELECT *
FROM Table1
WHERE CK_code IN (SELECT Field FROM Table2) -- here goes your subquery check
WITH CHECK OPTION;
当您尝试插入违反"约束的数据时#34;像:
INSERT INTO v_Table1(i, CK_Code)
VALUES(10, 'D');
你会得到:
尝试插入或更新失败,因为目标视图指定WITH CHECK OPTION或跨越指定WITH CHECK的视图 OPTION和操作产生的一行或多行没有 符合CHECK OPTION约束条件。
声明已经终止。
的 LiveDemo
强>