我想在应用程序的配置表中存储一行。我要强制该表只能包含一行。
强制单行约束的最简单方法是什么?
我想在应用程序的配置表中存储一行。我要强制该表只能包含一行。
强制单行约束的最简单方法是什么?
Name
?指定了不存在的值
ar
s评论的回应。问题是,如果您仅存储名称/值对,则值必须很好地为字符串,并且您无法在数据库中强制执行验证。当您对每个设置使用一个带有单独列的单行表时(如OP所希望的),则可以通过检查约束轻松地对每个配置设置实施验证。
Answers:
您确保其中一列只能包含一个值,然后确保主键(或应用唯一性约束)。
CREATE TABLE T1(
Lock char(1) not null,
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)
我在各种数据库中都有许多这样的表,主要用于存储配置。很高兴知道,如果config项应该是一个int,则只会从数据库中读取一个int。
comp.databases.theory
,是一个usenet小组(可通过Google小组查看),我承认我最近没有阅读太多内容。它比关系理论更着重于关系理论,而不是SQL-但我碰巧知道dportas / sqlvogel也经常光顾同一个小组。TTM引用了《第三宣言》,这是一本很好的书(再次)谈论关系理论而不是SQL。
我通常使用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')
)
添加“ DEFAULT'X'”,您将不必处理Lock列,也不必记住第一次加载表时哪个是锁值。
Lock char(1) not null CONSTRAINT DF_T1_Lock DEFAULT 'X'
您可能需要重新考虑此策略。在类似情况下,我经常发现留下旧配置行作为历史信息非常宝贵。
为此,您实际上有一个额外的列creation_date_time
(插入或更新的日期/时间)和一个插入或插入/更新触发器,可以使用当前日期/时间正确地填充它。
然后,为了获得当前配置,请使用类似以下内容的内容:
select * from config_table order by creation_date_time desc fetch first row only
(取决于您的DBMS风格)。
这样,您仍然可以维护历史记录以进行恢复(如果表太大,可以建立清除过程,但这不太可能),并且仍然可以使用最新配置。
SELECT TOP 1 ... ORDER BY creation_date_time DESC
这是我想出的一种解决方案,用于一个锁型表,该表只能包含一行,并持有Y或N(例如,应用程序锁定状态)。
用一列创建表。我将检查约束放在一列上,以便只能在其中输入Y或N。(或1或0,或其他)
以“正常”状态在表中插入一行(例如N表示未锁定)
然后在仅具有SIGNAL(DB2)或RAISERROR(SQL Server)或RAISE_APPLICATION_ERROR(Oracle)的表上创建INSERT触发器。这使得应用程序代码可以更新表,但是任何INSERT都会失败。
DB2示例:
create table PRICE_LIST_LOCK
(
LOCKED_YN char(1) not null
constraint PRICE_LIST_LOCK_YN_CK check (LOCKED_YN in ('Y', 'N') )
);
--- do this insert when creating the table
insert into PRICE_LIST_LOCK
values ('N');
--- once there is one row in the table, create this trigger
CREATE TRIGGER ONLY_ONE_ROW_IN_PRICE_LIST_LOCK
NO CASCADE
BEFORE INSERT ON PRICE_LIST_LOCK
FOR EACH ROW
SIGNAL SQLSTATE '81000' -- arbitrary user-defined value
SET MESSAGE_TEXT='Only one row is allowed in this table';
为我工作。
IF NOT EXISTS ( select * from table )
BEGIN
///Your insert statement
END
(Name, Value)
在Name上具有主键的列的表。然后,您select Value from Table where Name = ?
可以确定不会返回任何行或一行。