设置
这是两个简化的*表,说明了我遇到的问题
*实际的表格是这样构建的,因此我无法真正重构列或轻松地将它们分开
表:代码值
| <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/