视图上的外键引用

Posted

技术标签:

【中文标题】视图上的外键引用【英文标题】:Foreign-Key Reference on View 【发布时间】:2013-01-14 12:56:26 【问题描述】:

有没有可能引用一个视野来确保完整性?

伪代码示例:

CREATE VIEW V_ONE AS SELECT .....
CREATE TABLE TWO ( ID INT REFERENCES V_ONE ( field ))

想先CREATE TABLE T_ONE而不是V_ONE,以便能够引用T_ONE

@编辑:

View V_ONE 从 erp 系统的多个表中收集数据并对其进行预处理。表TWO 扩展了V_ONE 一些额外的数据,这些数据不应包含在V_ONE 中。对于V_ONE 中的每个条目,表TWO 中不能有一个条目,但我想确保表TWO 中没有在V_ONE 中找不到基本数据的条目。

【问题讨论】:

视图只是一个查询,没有数据可以验证,除非您在谈论基础表。你能解释一下为什么约束不能针对视图后面的任何表吗? 请发布视图的选择以及您要引用的字段的名称。 @AaronBertrand 该视图每行生成一个ID,用于对其数据的所有进一步处理,最好检查一下ID。视图本身被视为 ERP 表和 ERP-AddOn 之间的一种数据接口。 【参考方案1】:

简短的回答:不。 Sql Server 不允许在视图上使用外键。

您可以将外键约束放在视图中引用的“表之一”上,但没有上下文...很难给出方便的答案。

编辑:好吧,在两个上的 check constraint 怎么样,在 v_one 上有一个查询?

但是您必须找到一种方法来管理 v_one 的“源表”上的删除(和更新)。

您可以在视图 (V_ONE) 上使用(未经测试的)INSTEAD OF DELETE(和 INSTEAD OF UPDATE,如果需要)触发器,并在表上使用检查约束(两个)。

【讨论】:

更长的答案:***.com/questions/1928355/tsql-foreign-keys-on-views @mcalex:我知道链接的问题。但这并不完全涵盖我的问题。他要求通过将数据插入视图来确保数据完整性。相反,我想从表中引用视图! 使用触发器来实现约束怎么样? @tschmit007 也是这么想的。而不是在表二上插入触发器来检查 V_ONE 中的现有 PK。 @RaphaëlAlthaus ERP 表上的触发器不起作用。曾经使用过 DynamicsAX? ;)【参考方案2】:

您可以使用检查约束而不是外键来获得类似的结果:

-- CREATE VIEW THAT RETURNS DUMMY DATA
CREATE VIEW V_ONE
AS
SELECT  Field
FROM    (VALUES (1), (2), (3)) T (Field);
GO

-- CREATE FUNCTION THAT VALIDATES CRITERIA
CREATE FUNCTION dbo.CheckFunction (@ID INT)
RETURNS BIT AS
BEGIN

    IF EXISTS (SELECT 1 FROM V_ONE WHERE Field = @ID)
    BEGIN
        RETURN 1;
    END

    RETURN 0;

END
GO
-- CREATE TABLE THAT REFERENCES VIEW
CREATE TABLE T_TWO (ID INT NOT NULL CONSTRAINT CHK_T_TWO_ID CHECK (dbo.CheckFunction(ID) = 1));

-- TRY INSERTING A VALUE NOT RETURNED BY V_ONE
INSERT T_TWO VALUES (4);

您可能需要实现触发器来处理对 V_One 源的删除/更新,您也应该向源添加一个外键。

【讨论】:

以上是关于视图上的外键引用的主要内容,如果未能解决你的问题,请参考以下文章

Scaffold Rails 3 视图中的外键下拉列表

新 phpmyadmin 中的外键

两个外键引用一个表和可以为空的外键

Hibernate查询带有ID的外键字段

引用另一个模式的外键

作为 Entity Framework 6 中的外键的数据库计算属性