Can i use a SELECT statement to define a CHECK constraint?
In MS SQL server, can i use a SELECT statement to define a CHECK constraint? Say i have to work with two tables "Customer Master" and "Indian Customer" in ideal situation both tables are compleatly different, and are not interrelated in anyways. however they share the same database
Content of "Customer Master":
CustomerName (colomn): a, b, c, d, e
Branchlocation (colomn): IN, AU, IN, IN, UK
Content of "Indian Customer":
customerID (colomn): 1, 2, 3
CustomerNa开发者_如何学Gome (colomn): a, c, d
customer details (colomn): details1, details, details
.
.
.
In Table "Indian Customer" i want to put a constraint so that the users entring data in this table should not be able to enter customers that dont exist in "Customer Master" or whose branch location is not IN. also the tables are in the same project but are NOT directly related . In other words you can say Only indian customer from "Customer Master" should be in table "Indian Customer".
select CustomerName from "Customer Master"
where Branchlocation = 'IN'
the output of the above query should only be allowed in ["Indian Customer"].[CustomerName]
You can add some additional constraints and superkeys, and get what you want:
CREATE TABLE CustomerMaster (
CustomerName varchar(100) not null,
LocationCode char(2) not null,
constraint PK_CustomerMaster PRIMARY KEY (CustomerName),
constraint UQ_CustomerMaster_Location UNIQUE (CustomerName,LocationCode), /* <-- Superkey here */
constraint CK_CustomerMaster_Locations CHECK (
LocationCode in ('IN','UK','AU')
)
CREATE TABLE IndianCustomer (
CustomerID int not null,
CustomerName varchar(100) not null,
CustomerDetails varchar(max) not null,
LocationCode as 'IN' persisted,
constraint FK_IndianCustomer_CustomerMaster FOREIGN KEY (CustomerName,LocationCode) references CustomerMaster (CustomerName,LocationCode)
)
By having LocationCode as a computed column in IndianCustomer, and having the foreign key against the superkey, you're ensuring the data matches.
You can define an additional FK constraint just for CustomerName -> CustomerName, this can prove useful in some circumstances.
Or, to put it another way - there is one, highly stylised way to construct a constraint based on a "select" statement - and that is a FOREIGN KEY. But you sometimes have to add additional information (such as super keys, computed columns) to satisfy additional filtering requirements.
Normally 3 ways
First way, best, using DRI
- define an extra column Branchlocation in "Indian Customer"
- add a CHECK CONSTRAINT to limit it to "IN"
- add a unique constraint on "Customer Master" for CustomerName/ID, Branchlocation
- foreign key on both CustomerName/ID, Branchlocation from "Indian Customer" to "Customer Master"
This works cleanly without code or triggers
Edit: as per Damien_The_Unbeliever's answer
Second way, OK, triggers
- On insert or update of "Indian Customer", check Customer Master
Third way, not so good, use a function
- A check constraint on "Indian Customer" uses a function to hide the SELECT
This is not safe for concurrency and is not guaranteed to work
NOTE:- As far as I know, there is no possible way to check constraint using a select statement. However for your case you can use a simple select query with where clause as given below
select * from A
where somecolumn not in
( select somecolumn from B where <condition for B> )
For your query, assuming you have sno as foreignkey in B -
select somedata from A
where someforeignKey = ( select sno from B where sno = 55 )
精彩评论