Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server条件外键_Sql_Sql Server_Foreign Keys_Conditional Statements - Fatal编程技术网

SQL Server条件外键

SQL Server条件外键,sql,sql-server,foreign-keys,conditional-statements,Sql,Sql Server,Foreign Keys,Conditional Statements,我的SQLServer数据库中有两个表,Foo和Bar。表Foo是这样的: +-------+ | Foo | +-------+ | Id | | Type | | Value | +-------+ +----------+ | Bar | +----------+ | Id | | TypeId | | StatusId | | StateId | +----------+ 该表具有如下值: +----+--------+-----------+

我的SQLServer数据库中有两个表,Foo和Bar。表Foo是这样的:

+-------+
|  Foo  |
+-------+
| Id    |
| Type  |
| Value |
+-------+
+----------+
|   Bar    |
+----------+
| Id       |
| TypeId   |
| StatusId |
| StateId  |
+----------+
该表具有如下值:

+----+--------+-----------+
| Id |  Type  |   Value   |
+----+--------+-----------+
|  1 | Status | New       |
|  2 | Status | Old       |
|  3 | Type   | Car       |
|  4 | State  | Inventory |
|  5 | State  | Sold      |
+----+--------+-----------+
表格栏如下所示:

+-------+
|  Foo  |
+-------+
| Id    |
| Type  |
| Value |
+-------+
+----------+
|   Bar    |
+----------+
| Id       |
| TypeId   |
| StatusId |
| StateId  |
+----------+
其中
TypeId
StatusId
StateId
都是Foo表的外键。 但是我想在每个外键上设置一个条件,即它们只能使用Foo的键 与它的类型相关的ID。例如,
TypeId
列只能是id的外键 3在桌上。或者,
StatusId
列只能使用IDS1或IDS2的外键

我知道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)

但这不起作用。我做错了什么?

您所指的检查约束仅用于限制键列或非键列中存储的信息类型。所以,如果您不希望某个键列具有负值(假设它是一个price列,并且永远不存在负值),您将使用Check约束

要更好地理解主键和外键的概念,请执行以下操作:

主键唯一地标识表中的每条记录。 外键是某个表中的值,它是另一个表中的唯一标识符(也可以是主键)。这意味着外键可以在其作为外键的表中重复多次,并且它在创建它的表中(在赋予它意义的表中)肯定是唯一的

现在来回答您的问题,您可能需要使用复合键的概念。复合键基本上是由两个或多个值组成的一组,它们唯一地标识一个记录,因为您无法按预期的方式对外键实施限制,因为这会破坏键的用途。在应用程序层而不是数据库层处理密钥中存储的数据类型的一些问题


以这种方式查看问题在概念上也可以解决表中的一些设计缺陷。

检查用于确保列中的值在某些硬编码值内。这根本不是你想要的。您需要的是使用函数的约束。“外键”不是动词,而是名词。:)我认为外键不是你想要的。这在某种程度上与“多态外键”有关,但并不完全相同。您可以使用列扩展
,例如
'Status'
等词(可以计算,但必须持久化),然后在引用
foo
中的
id
type
的数字-单词对上放置外键约束(可能在
foo
中声明对主键或唯一键后)。否则你必须在
条上创建一个触发器,按你想要的方式检查它。只需添加我的2美分,但这是一个糟糕的设计。创建
类型
状态
状态
表;为他们创建一个合适的FK,让SQL完成它的工作,并就此结束。当输入无效组合时,任何使此引发错误的操作都将是一种黑客行为。