sql - 将 FK/约束添加到表的子部分

标签 sql sql-server foreign-keys check-constraints

设置

这是两个简化的*表,说明了我遇到的问题
*实际的表格是这样构建的,因此我无法真正重构列或轻松地将它们分开

表:代码值

| <b>Code<i>Set</i></b> | <b>Code<i>Value</i></b> | <b>Code<i>Text</i></b> |
|---------|-----------|----------|
| States  | 1         | Vermont  |
| States  | 2         | Hawaii   |
| YN      | 1         | Yes      |
| YN      | 2         | No       |

其中 CodeSet + CodeValue 是复合主键

表:地址

| <b>AddressID</b> | <b>Zip</b>   | <b>State</b> |
|-----------|-------|-------|
| 1         | 96701 | 2     |
| 2         | 05001 | 1     |
| 3         | 05602 | 1     |

其中AddressID是主键


添加到 Address.State 的适当数据库约束是什么?

它应该始终CodeValuesWhere CodeSet = 'States' 中存在的值,但我不相信我可以创建 Foreign Key that is part of a Composite Primary Key

是否应该只是 check constraint based on a query像这样吗?

CREATE FUNCTION checkCodeValues(
    @codeSet   VARCHAR(50),
    @codeValue SMALLINT

)
RETURNS BIT
AS
BEGIN
    IF EXISTS (SELECT * FROM CodeValues WHERE CodeSet = @codeSet
                                          AND CodeValue = @codeValue)
        RETURN 1
    RETURN 0
END
ALTER TABLE Address
    WITH CHECK ADD CONSTRAINT CK_State
    CHECK (checkCodeValues('States', State))

我担心的是,当它确实是 FK 时,数据库设计工具不会真正识别该约束的全部影响,而只是针对表的一小部分。

最佳答案

一种方法使用更多的存储空间,但它可以实现您想要的:

create table addresses (
    . . .,
    codeset as (convert(varchar(?), 'states')) persisted,
    foreign key (codeset, state) references codevalues (codeset, codevalue)
);

? 表示 codevalues 表中 varchar() 列的长度。

令人高兴的是,您不需要触发器或用户定义的函数来完成此操作。

不幸的是,您需要在每一行中保留代码集,这样会占用表中的一点空间。

关于sql - 将 FK/约束添加到表的子部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55928678/

相关文章:

mysql - 如何检索每个 ID 的最新和第二个最新日期?

SQL Server存储过程插入重复行

计算每个时间间隔增长的 SQL 语句

sql-server - 我有一个不正确的语法错误

sql - 调用存储过程(SQL)获取用户的IP地址

sql - SQL Server 中的多个单独的 IF 条件

html - 将数据粘贴到 MS Excel 时避免换行 (<br/>)

postgresql - Postgres : Are Nested Foreign Keys allowed?

mysql - 错误 1215 外键约束

python - 如何在 Django 1.5 中使用 'User' 作为外键