当前位置:  开发笔记 > 编程语言 > 正文

仅标记为默认的一条记录的约束

如何解决《仅标记为默认的一条记录的约束》经验,为你挑选了3个好方法。

如何在表上设置约束,以便只有一个记录的isDefault位字段设置为1?

约束不是表范围,而是由FormID指定的每组行的一个默认值.



1> Yves M...:

使用唯一的筛选索引

在SQL Server 2008或更高版本上,您只需使用唯一的筛选索引即可

CREATE UNIQUE INDEX IX_TableName_FormID_isDefault
    ON TableName(FormID)
    WHERE isDefault = 1

表是哪里的

CREATE TABLE TableName(
    FormID INT NOT NULL,
    isDefault BIT NOT NULL
)

例如,如果您尝试插入多个具有相同FormId且isDefault设置为1的行,则会出现此错误:

无法在对象'dbo.TableName'中插入具有唯一索引'IX_TableName_FormID_isDefault'的重复键行.重复键值为(1).

资料来源:http://technet.microsoft.com/en-us/library/cc280372.aspx


过滤的索引需要ANSI PADDING ON.因此,在创建过滤索引之前执行`SET ANSI PADDING ON`.

2> Tom Future..:

这是Damien_The_Unbeliever解决方案的修改,允许每个FormID一个默认值.

CREATE VIEW form_defaults
AS
SELECT FormID
FROM whatever
WHERE isDefault = 1
GO
CREATE UNIQUE CLUSTERED INDEX ix_form_defaults on form_defaults (FormID)
GO

但是严肃的关系人会告诉你这些信息应该只在另一张表中.

CREATE TABLE form
FormID int NOT NULL PRIMARY KEY
DefaultWhateverID int FOREIGN KEY REFERENCES Whatever(ID)


+1"严肃的关系人会做什么"回答..我从有一个布尔值分成一个单独的表

3> Ian Nelson..:

从标准化的角度来看,这将是存储单个事实的低效方式.

我会选择通过将(在不同的表中)外键存储到被认为是默认行的行的标识符(更高级别)来保存此信息.

CREATE TABLE [dbo].[Foo](
    [Id] [int] NOT NULL,
 CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[DefaultSettings](
    [DefaultFoo] [int] NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[DefaultSettings]  WITH CHECK ADD  CONSTRAINT [FK_DefaultSettings_Foo] FOREIGN KEY([DefaultFoo])
REFERENCES [dbo].[Foo] ([Id])
GO

ALTER TABLE [dbo].[DefaultSettings] CHECK CONSTRAINT [FK_DefaultSettings_Foo]
GO


是的,但是这个替代解决方案仍然允许通过在dbo.DefaultSettings中插入许多行来实现多个默认值.如果你选择了那个方法,可以在dbo.DefaultSettings中添加一个触发器,只允许在那里有1行.
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有