【发布时间】:2018-08-19 02:25:24
【问题描述】:
我的 SQL Server 数据库中有两个表,Foo 和 Bar。 Table Foo 是这样的:
+-------+
| Foo |
+-------+
| Id |
| Type |
| Value |
+-------+
该表的值如下:
+----+--------+-----------+
| Id | Type | Value |
+----+--------+-----------+
| 1 | Status | New |
| 2 | Status | Old |
| 3 | Type | Car |
| 4 | State | Inventory |
| 5 | State | Sold |
+----+--------+-----------+
表格栏是这样的:
+----------+
| Bar |
+----------+
| Id |
| TypeId |
| StatusId |
| StateId |
+----------+
其中TypeId、StatusId 和StateId 都是 Foo 表的外键。
但我想对每个外键设置一个条件,它们只能对 Foo 进行键控
与其类型相关的 ID。例如,TypeId 列只能外键到 id
3 在 Foo 表上。或者StatusId 列只能是 ids 1 或 2 的外键。
我知道 SQL Server 中有一个检查功能,但我不确定如何正确使用它。我 试图做这样的事情:
CREATE TABLE TEST.dbo.Bar
(
Id int PRIMARY KEY NOT NULL IDENTITY,
TypeId int NOT NULL CHECK (Type='Type'),
CONSTRAINT FK_Bar_Foo_Type FOREIGN KEY (TypeId) REFERENCES Foo (Id, Type)
)
CREATE UNIQUE INDEX Bar_Id_uindex ON TEST.dbo.Bar (Id)
但这没有用。我做错了什么?
【问题讨论】:
-
CHECK 用于确保列中的值在某些硬编码值范围内。这根本不是你想要的。您需要的是使用函数的约束。这个问题已经被问了几十次了。
-
FWIW“外键”不是动词,而是名词。 :)
-
我不认为外键能如你所愿。这有点与“多态外键”有关,但又不太一样。
-
您可以扩展
bar,例如'Status'之类的列(可以计算但必须持久化),然后在引用@ 的数字词对上放置外键约束foo中的 987654332@ 和type(可能在foo中声明了对主键或唯一后)。否则,您必须在bar上创建一个触发器,以按照您想要的方式进行检查。 -
只是加上我的 2 美分,但这是一个糟糕的设计。创建
type、status和state表;为他们创建一个适当的 FK,让 SQL 完成它的工作,然后收工。当输入无效的组合时,你所做的任何事情都会引发错误,这将是一种黑客攻击。
标签: sql sql-server foreign-keys conditional-statements