SQL Server约束帮助
在SQLServer2005中,我在制定适当的约束方面遇到了问题。我的问题涉及以下表格:SQL Server约束帮助,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,在SQLServer2005中,我在制定适当的约束方面遇到了问题。我的问题涉及以下表格: Table PKTable { pk integer primary key, property integer, } Table FKTable { pk integer primary key, fk integer references PKTable(pk), } 我真的想让记录fk_rec在它引用的PKTable记录的property=5时不可能存在。我尝试做的第一件事是使用
Table PKTable
{
pk integer primary key,
property integer,
}
Table FKTable
{
pk integer primary key,
fk integer references PKTable(pk),
}
我真的想让记录fk_rec在它引用的PKTable记录的property=5时不可能存在。我尝试做的第一件事是使用以下查询创建一个绑定到模式的视图,并在UniqueCol字段上创建一个唯一的索引
SELECT 'True' AS UniqueCol, 'uh oh' AS DiffCol
FROM FKTable INNER JOIN
PKTable ON FKTable.fk = PKTable.pk
WHERE PKTable.property = 5
UNION
SELECT 'True' AS UniqueCol, 'default' AS DiffCol
因此,基本上,'True','default')记录将始终存在于视图中,当有人试图在FKTable中插入一行并且它引用的PKTable记录的属性为5时,我会得到一个约束冲突,因为上面的union查询的第一部分将返回一些内容。无论如何,这就是我的想法。但是,SQLServer2005不允许对涉及联合的视图进行索引。然后我尝试创建另一个视图:
SELECT UniqueCol, DiffCol FROM TheViewAbove
在这种情况下,在UniqueCol上放置唯一索引失败,因为在引用另一个视图的视图上不能有索引。我知道这是不可能的。有什么办法可以解决这个问题吗
谢谢 两种方式
NonProp5s
,其中只有non属性=5行,然后从FKTable而不是主PKTable中引用此子类型表中的pk。此子类型表中不需要有pk列以外的任何内容,(创建表NonProp5s(pk Integer主键不为Null)
关键在于,插入父pkTable时,总是会在非Prop5s
中插入一行pk值相同的行,除非属性值等于5。(每当pkTable中的属性值更改为/从5更改时,您还需要一个更新触发器来插入/删除行。)NonProp5s
,其中只有non属性=5行,然后从FKTable而不是主PKTable中引用此子类型表中的pk。此子类型表中不需要有pk列以外的任何内容,(创建表NonProp5s(pk Integer主键不为Null)
关键在于,插入父pkTable时,总是会在非Prop5s
中插入一行pk值相同的行,除非属性值等于5。(每当pkTable中的属性值更改为/从5更改时,您还需要一个更新触发器来插入/删除行。)我真的不想更改表或表之间的关系,因此我所做的是: 我创建了一个名为
DummyTable
的表,其中包含多条记录。我在其中放入了2条记录。然后我构建了一个视图:
SELECT pk FROM FKTable
INNER JOIN PKTable ON FKTable.fk = PKTable.pk
INNER JOIN DummyTable ON 1 = 1
WHERE PKTable.property = 5
然后,我在视图的pk字段上放置了一个唯一索引。这样,当存在违反我约束的a行时,我将获得重复的索引。我真的不想更改表或表之间的关系,因此我所做的是: 我创建了一个名为
DummyTable
的表,其中包含多条记录。我在其中放入了2条记录。然后我构建了一个视图:
SELECT pk FROM FKTable
INNER JOIN PKTable ON FKTable.fk = PKTable.pk
INNER JOIN DummyTable ON 1 = 1
WHERE PKTable.property = 5
然后,我在视图的pk字段上放置了一个唯一索引。这样,当存在违反我的约束的a行时,我将获得重复的索引。您还可以使用触发器来实现约束,如下所示: 首先创建表:
CREATE TABLE tPK(
ID int NOT NULL PRIMARY KEY
,[Property] int NULL
)
go
CREATE TABLE tFK(
ID int NOT NULL PRIMARY KEY
,fk int NOT NULL
)
go
ALTER TABLE tFK ADD
CONSTRAINT FK1_tFK FOREIGN KEY(fk) REFERENCES tPK(ID)
ON UPDATE CASCADE
ON DELETE CASCADE
go
然后将触发器添加到父表中
CREATE TRIGGER trgPK ON tPK
AFTER INSERT, UPDATE
AS
IF UPDATE(Property)
BEGIN
DELETE FROM tFK
WHERE fk IN ( SELECT T.ID
FROM tPK AS T
WHERE T.[Property] = 5 )
END
go
在子表上:
CREATE TRIGGER trgFK ON dbo.tFK
AFTER INSERT, UPDATE
AS
IF UPDATE(fk)
BEGIN
DELETE FROM tFK
WHERE fk IN ( SELECT T.ID
FROM tPK AS T
WHERE T.[Property] = 5 )
END
GO
如果要进行大量加载,则:
您还可以使用触发器来实现约束,如下所示: 首先创建表:
CREATE TABLE tPK(
ID int NOT NULL PRIMARY KEY
,[Property] int NULL
)
go
CREATE TABLE tFK(
ID int NOT NULL PRIMARY KEY
,fk int NOT NULL
)
go
ALTER TABLE tFK ADD
CONSTRAINT FK1_tFK FOREIGN KEY(fk) REFERENCES tPK(ID)
ON UPDATE CASCADE
ON DELETE CASCADE
go
然后将触发器添加到父表中
CREATE TRIGGER trgPK ON tPK
AFTER INSERT, UPDATE
AS
IF UPDATE(Property)
BEGIN
DELETE FROM tFK
WHERE fk IN ( SELECT T.ID
FROM tPK AS T
WHERE T.[Property] = 5 )
END
go
在子表上:
CREATE TRIGGER trgFK ON dbo.tFK
AFTER INSERT, UPDATE
AS
IF UPDATE(fk)
BEGIN
DELETE FROM tFK
WHERE fk IN ( SELECT T.ID
FROM tPK AS T
WHERE T.[Property] = 5 )
END
GO
如果要进行大量加载,则:
@Nitai-那不行。你读对问题了吗?@Alex-我可能会按照你的建议去做。我以前做过,我不知道为什么我会回避改变这里的表格。@Nitai-那不行。你读对问题了吗?@Alex-我可能会按照你的建议去做。我以前做过,我不是我不知道为什么我不敢在这里换桌子。