2

我有两个表,A 和 B。结构如下所示:

CREATE TABLE A (
    w int NOT NULL,
    x int NOT NULL,
    y int NOT NULL,
    CONSTRAINT PK_A PRIMARY KEY (w, x, y)
)

CREATE TABLE B (
    w int NOT NULL,
    y int NULL,
    z int NOT NULL
)

我想确保在表 B 中输入的任何一组值,w 和 y 在表 A 中。如果表 B 中的 y 值为空,我只想确保 w 在表 A 中。

一些示例数据、插入和预期结果:

Table A
w  x  y
----------
1  1  1
1  1  2
1  2  1
1  3  2
2  1  1

INSERT INTO B (w, y, z) VALUES (1, 1, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, NULL, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, 1, 4) -- good
INSERT INTO B (w, y, z) VALUES (2, NULL, 3) -- good
INSERT INTO B (w, y, z) VALUES (1, 3, 1) -- fail
INSERT INTO B (w, y, z) VALUES (3, NULL, 1) -- fail

这有什么办法吗?如果它发挥作用,我正在使用 SQL Server 2000。

4

1 回答 1

2

不幸的是,您不能在 和 上使用外键约束B.wB.y因为它们会引用 上的非唯一列A。但是您可以通过触发器添加此检查:

create trigger check_w on B for insert, update
as
if not exists(select * from A join inserted on A.w = inserted.w) 
begin
  raiserror('W not in A!', 1, 1)
  rollback transaction
end

GO

create trigger check_y on B for insert, update
as
if 
(select y from inserted) is not null and 
not exists(select * from A join inserted on A.y = inserted.y) 
begin
  raiserror('Y not null and not in A!', 1, 1)
  rollback transaction
end

GO

您绝对可以将这两个触发器合二为一。

另请注意,您需要在 A 上触发delete操作。如果 B 上有匹配的行,您要么阻止删除,要么执行级联删除操作。

于 2012-08-30T16:44:26.093 回答