我可以使用 SELECT 语句来定义 CHECK 约束吗?

发布于 2024-10-10 13:20:50 字数 729 浏览 1 评论 0原文

在 MS SQL Server 中,我可以使用 SELECT 语句来定义 CHECK 约束吗?假设我必须使用两个表“Customer Master”和“Indian Customer”,在理想情况下,这两个表完全不同,并且无论如何都不相互关联。但是它们共享相同的数据库,

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

在表“印度客户”中,我想设置一个约束,以便在此表中输入数据的用户不能输入“客户主数据”中不存在的客户或其分支位置不在IN中。这些表也位于同一项目中,但不直接相关。换句话说,您可以说只有来自“客户主”的印度客户应该位于“印度客户”表中。

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

上述查询的输出只能在 ["Indian Customer"].[CustomerName] 中允许

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
CustomerName  (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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮华 2024-10-17 13:20:50

您可以添加一些额外的约束和超级键,并获得您想要的结果:

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 中的计算列,并使用针对超级键的外键,您可以确保数据匹配。

您可以仅为 CustomerName -> 定义额外的 FK 约束CustomerName,这在某些情况下很有用。


或者,换句话说 - 有一种高度风格化的方法来构建基于“select”语句的约束 - 这就是外键。但有时您必须添加额外的信息(例如超级键、计算列)来满足额外的过滤要求。

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.

与往事干杯 2024-10-17 13:20:50

通常有 3 种方法

第一种方法,最好的方法是使用 DRI

  • 在“Indian Customer”中定义一个额外的列 Branchlocation
  • 添加 CHECK CONSTRAINT 以将其限制为“IN”
  • 在“Customer Master”上为 CustomerName/ID 添加唯一约束,
  • 在两者上添加 Branchlocation 外键CustomerName/ID,分支位置从“Indian Customer”到“Customer Master”

这无需代码或触发器即可干净地工作

编辑:根据Damien_The_Unknowner的回答

第二种方式,好的,触发器

  • 在插入或更新“Indian Customer”时,检查Customer Master

第三种方式,不太好,使用函数

  • 对“Indian Customer”的检查约束使用函数来隐藏 SELECT

这对于并发来说不安全,并且不能保证工作

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

小…红帽 2024-10-17 13:20:50

注意:- 据我所知,没有可能使用 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 ) 

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 ) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文