2011-01-05 121 views
2

在MS SQL服务器中,我可以使用SELECT语句来定义CHECK约束吗?假设我必须在理想情况下使用两张表格“客户主人”和“印度客户”,两张表格完全不同,并且无论如何都不相互关联。然而,它们共享同一个数据库我可以使用SELECT语句来定义CHECK约束吗?

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 
CustomerName (colomn): a, c, d 
customer details (colomn): details1, details, details 
. 
. 
. 

表“印客”我想提出一个约束,使用户entring在这个表中的数据不应该是能够输入不要在“客户主”存在的客户或其分支位置不是IN。这些表格也在同一个项目中,但是与不直接相关。换句话说,你可以说只有来自“客户主人”的印度客户应该在“印度客户”表中。

select CustomerName from "Customer Master" 
where Branchlocation = 'IN' 

上述查询的输出应该只在[“印客”]允许[客户名称]

+1

,请您提供一些具体的例子。 Select语句用于检索数据,Check用于验证数据。所以我不明白你在这里做什么。 – 2011-01-05 07:03:09

+0

同意。你的例子不是检查约束,而是一个选择过滤器。也许一本关于SQL初学者的书是在替代?阅读它可能会清除一些混淆。投票结束 - 问题不清楚。 – TomTom 2011-01-05 07:09:12

+0

@汤姆汤姆:也许如果你读过这个问题,你可能会理解它。 'SELECT语句来定义一个CHECK'意味着我在check子句中使用子查询。 – 2011-01-05 07:22:54

回答

3

你可以添加一些额外的约束和superkeys,并得到你想要的东西:

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) 
) 

通过其LocationCode在IndianCustomer计算列,并具有针对super键外键,你保证数据匹配。

您可以为CustomerName - > CustomerName定义一个额外的FK约束,这在某些情况下证明是有用的。


或者,换一种方式 - 有一个,构建基于“select”语句的限制高度程式化的方式 - 这是一个外键。但是您有时必须添加其他信息(例如超级键,计算列)以满足其他过滤要求。

0

注意: - 。据我所知,目前还没有可能的方式来检查使用select语句进行约束。然而,对于你的情况,你可以使用带有where子句一个简单的选择查询以下

select * from A 
where somecolumn not in 
(select somecolumn from B where <condition for B>) 

您所查询的是给定的,假设你在B具有SNO为外键 -

select somedata from A 
where someforeignKey = (select sno from B where sno = 55) 
+0

-1 ,.两者都没有定义检查约束。当然,OP似乎并不知道他想问什么,但这些几乎都是正常的过滤条款,而不是检查约束。 – TomTom 2011-01-05 07:10:01

+0

@TomTom - 是的,从OP给出的示例查询,这是我可以与之合作。目前有修改的答案添加一个说明,说不可能用select语句检查约束。 – 2011-01-05 10:47:49

1

正常情况下3种方式

第一种方式,最好的,使用DRI

  • 定义 “印客” 一个额外的列Branchlocation
  • 添加一个检查约束限制为 “IN”
  • 从“印客”到“客户主”添加唯一约束的“客户主”的客户名称/ ID,Branchlocation
  • 外键的两个客户名称/ ID,Branchlocation

此作品干净无代码或触发

编辑:按Damien_The_Unbeliever的答案

方式二,OK,触发

  • 在插入或 “印客” 的更新,检查客户主

第三条道路,不是那么好,使用函数

  • 的 “印客” 检查限制使用的功能隐藏SELECT

This is not safe for concurrency and is not guaranteed to work

+1

第二种方式,触发器 - 您还需要在客户主数据上触发,以处理对位置的删除和更新。 – 2011-01-05 08:17:46