SQL Server:如何约束表包含单个行?

Mar*_*tin 73 sql-server singleton database-design

我想在我的应用程序的配置表中存储一行.我想强制说这个表只能包含一行.

实施单行约束的最简单方法是什么?

Dam*_*ver 90

您确保其中一列只能包含一个值,然后将其作为主键(或应用唯一性约束).

CREATE TABLE T1(
    Lock char(1) not null,
    /* Other columns */,
    constraint PK_T1 PRIMARY KEY (Lock),
    constraint CK_T1_Locked CHECK (Lock='X')
)
Run Code Online (Sandbox Code Playgroud)

我在各种数据库中有许多这些表,主要用于存储配置.知道如果配置项应该是int,那么你只会从数据库中读取一个int,这样会更好.

  • +1。这是 Celko 在“SQL for Smarties”中用于辅助常量表的方法 (2认同)
  • @BZ - cdt 是 `comp.databases.theory` 的简写,这是一个 usenet 组(通过​​ Google 组可见),我承认我最近没有阅读太多。它比 SQL 更侧重于关系理论 - 但我碰巧知道 dportas/sqlvogel 也经常光顾同一组。TTM 引用了 [The Third Manifesto](http://en.wikipedia.org/wiki/The_Third_Manifesto),这是一本(再次)谈论关系理论而不是 SQL 的好书。 (2认同)

小智 48

我通常使用Damien的方法,这对我来说一直很好,但我还添加了一件事:

CREATE TABLE T1(
    Lock char(1) not null DEFAULT 'X',
    /* Other columns */,
    constraint PK_T1 PRIMARY KEY (Lock),
    constraint CK_T1_Locked CHECK (Lock='X')
)
Run Code Online (Sandbox Code Playgroud)

添加"DEFAULT'X'",您将永远不必处理Lock列,并且不必记住第一次加载表时哪个是锁定值.

  • 还应该命名默认约束,否则它将获得一个自动生成的令人困惑的名称。`Lock char(1)不为空CONSTRAINT DF_T1_Lock DEFAULT'X' (2认同)
  • 此外,您应该将默认值设为“X”以外的值。我创建了一个更长的字符串,如果我尝试插入第二行,这就是我的错误消息:违反主键约束“PK_RestrictToOneRow”。无法在对象“dbo.1ROWTABLE”中插入重复的键。重复的键值是(该表被锁定到一行)。 (2认同)

pax*_*blo 14

您可能想重新考虑这个策略.在类似的情况下,我经常发现保留旧的配置行以获取历史信息是非常宝贵的.

为此,您实际上有一个额外的列creation_date_time(插入或更新的日期/时间)和插入或插入/更新触发器,它将使用当前日期/时间正确填充它.

然后,为了获得当前配置,您可以使用以下内容:

select * from config_table order by creation_date_time desc fetch first row only
Run Code Online (Sandbox Code Playgroud)

(取决于您的DBMS风味).

这样,你仍然可以维护恢复目的的历史记录(如果表格太大但你不太可能建立清理程序),你仍然可以使用最新的配置.


Joh*_*som 5

您可以实现INSTEAD OF 触发器,以在数据库中实施这种类型的业务逻辑。

触发器可以包含检查表中是否已存在记录的逻辑,如果存在,则回滚插入。

现在,退后一步来查看大图,我想知道是否存在另一种更合适的方式来存储此信息,例如存储在配置文件或环境变量中?