I have table designed in SQL-Server
2008 R2.
I have a column in that table which needs to be checked against another table when data is inserting.
ALTER TABLE Table1
WITH CHECK ADD CONSTRAINT CK_Code
CHECK (MyField in (Select Field From Table2))
This cause an error
Sub-queries are not allowed in this context. Only scalar expressions are allowed.
I have looked at this question about Check Constraint - Subqueries are not allowed in this context.
Is there any way of achieving this without using a trigger?
Note, what you really want is a foreign key constraint. That said, to get a "query" into a check you can write a function that contains the query and outputs a scalar value, then use that function in the check constraint.
CREATE FUNCTION myFunction (
@field DATATYPE(?)
)
RETURNS VARCHAR(5)
AS
BEGIN
IF EXISTS (SELECT* FROM Table2 WHERE MYFIELD = @field)
return 'True'
return 'False'
END
Something like that. Not tested.
Then you can add it to your check like so
ALTER TABLE Table1
WITH CHECK ADD CONSTRAINT CK_Code
CHECK (myFunction(MYFIELD) = 'True')
You can't have sub queries inside check constraints. What you can do is use a UDF that returns a scalar value inside the check constraint.
Step 1: Create the table
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
)
Step 2 : Create the UDF that returns a scalar
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
Step 3 : Alter table to add the CHECK constraint
ALTER TABLE RawMaterialByGender
ADD CONSTRAINT check_LevelMasterID CHECK (dbo.IsValidLevelMasterGender(LeveLMasterID) = 'true')
ALTER TABLE Table1
ADD CONSTRAINT FK_Table1_Code FOREIGN KEY (MyField)
REFERENCES Table2 (Field) ;
Ref: http://msdn.microsoft.com/en-us/library/ms190273.aspx
Note: I haven't checked the above for syntax.
First of all in your example you clearly need FK Constraint.
Another posibility is to use view with WITH CHECK OPTION
and give access to user through it:
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;
When you try to insert data that violates your "constraint" like:
INSERT INTO v_Table1(i, CK_Code)
VALUES(10, 'D');
You will get:
The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view that specifies WITH CHECK OPTION and one or more rows resulting from the operation did not qualify under the CHECK OPTION constraint.
The statement has been terminated.
来源:https://stackoverflow.com/questions/13000698/sub-queries-in-check-constraint