t-sql多个记录的单个默认值

时间:2013-04-15 20:43:28

标签: sql sql-server-2008 database-design triggers

我有一个MSSQL Server 2008表,它将多张照片关联到房屋,如下所示:

HouseID - with foreign key to House table
PhotoID - with foreign key to Photo table

这一切都很有效,PhotoID上有一个独特的约束条件,因此照片无法与多个房屋相关联。

我想为房屋记录指定默认照片。该表如此更新

HouseID
PhotoID
isDefault

问题是,对于一套房子的照片,只能有一个isDefault = 1。

在MSSQL Server 2008中,如何确保给定的House ID只有一个isDefault = 1,其他记录是isDefault = 0?使用触发器更好,还是有更好的方法?如果是触发器,对语法有什么建议可以确保优化吗?

最后,我需要这个来处理Insert和Update事件。

更新

以下工作就像一个魅力。评论

CREATE VIEW HousePhoto_isDefault AS 
SELECT yourSchema.HousePhoto.houseID, yourSchema.HousePhoto.isDefault
FROM yourSchema.HousePhoto WHERE isDefault = 1
GO

CREATE UNIQUE CLUSTERED INDEX idx_HousePhoto_isDefault
ON HousePhoto_isDefault (houseID)
GO

4 个答案:

答案 0 :(得分:0)

正如您所描述的那样,您需要使用触发器。

但是,如果你对数据结构做了一些小改动,我认为你可以通过常规约束来做到这一点。而不是在照片级别存储isDefault,而是将DefaultPhotoId存储在房屋级别。这样,无论你做什么,你都不会有多张默认照片。

如果您想确保有默认值,请将其设置为NOT NULL

答案 1 :(得分:0)

  

在MSSQL Server 2008中,如何确保给定的House ID只有一个isDefault = 1,其他记录是isDefault = 0?

为什么是Yves Samèr指出this answer你可以使用过滤索引

CREATE UNIQUE INDEX photo_isDefault 
    ON Photos(HouseID) WHERE isDefault = 1 

DEMO

产生的错误是

  

无法在对象'dbo.Photos'中插入重复的关键行   index'photo_isDefault':插入照片(houseID,isDefault)   价值观(1,1)

你也可以选择使用INDEXED VIEW,或者你也注意到触发器也会这样做。

答案 2 :(得分:0)

我实际上认为触发器可能过度杀伤。只需使用CASE语句。以下是UPDATE语句的示例(使用您正在使用的任何脚本语言替换变量):

UPDATE HousePhoto
SET isDefault = 
(
    CASE
        WHEN
            (PhotoID = @PhotoID)
        THEN
            1
        ELSE
            0
    END
)
WHERE HouseID = @HouseId

当然,你总是可以使用两个查询。

  UPDATE HousePhoto SET isDefault = 0 WHERE HouseID = @HouseID
  UPDATE HousePhoto SET isDefault = 1 WHERE HouseID = @HouseID AND PhotoID = @PhotoID

答案 3 :(得分:0)

还有另一种方法:使用“反向”FK:

ER Model

[SQL Fiddle]

Photo{HouseId, PhotoNo}中注意identifying关系和最终复合PK的使用至关重要。这有两个目的:

  • 确保如果照片是某个房屋的默认照片,则必须属于相同的房屋。
  • 使House复合中的FK成为可能。由于其中一个FK字段也在PK(HouseId)中,因此它不能为NULL,因此使另一个可以为NULL的字段(DefaultPictureNo)至关重要。如果任何的FK字段为NULL,则不会强制执行FK,这样我们就可以在存在此类数据的情况下插入新数据 1 时打破鸡与蛋的问题圆形FK。

与使用isDefault标志和关联的过滤索引相比,此方法进行了以下权衡:

  • PRO:避免额外字段的开销。如果与默认图片的数量相比,图片总数非常高,这可能很重要。
  • CON:对Photo PK使用自动增量是不切实际的。
  • CON:如果您尝试在存在此类循环FK的情况下使用声明性引用操作(例如ON DELETE CASCADE),MS SQL Server将会抱怨。您需要使用触发器实现参照操作。这是一个MS SQL Server怪癖,通常不适用于其他DBMS。
  • TIE:Pictureclustering的干扰较少,代价是干扰House中的聚类。 2
  • PRO:它适用于不支持过滤索引的DBMS(这里不是很重要,但值得一提)。

1 I.e。使我们能够插入一个房子而不立即设置默认图片,这是不可能的,因为这是一个新房子,还没有图片。

2 在群集表中,辅助索引可能很昂贵,House中的FK需要支持索引。