如何强制表只有一行?以下是我的尝试.该UPDATE触发器可以工作,但是,CREATE触发绝对不会.SET但是,对于CREATE,我想使用SETSQLite不支持.
CREATE TABLE IF NOT EXISTS `config` (
`id` TINYINT NOT NULL DEFAULT 0,
`subdomain` VARCHAR(45) NOT NULL,
`timezone` CHAR(3) NOT NULL,
`timeout` TINYINT NOT NULL,
`offline` TINYINT NOT NULL,
`hash_config` CHAR(32) NOT NULL,
`hash_points` CHAR(32) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO config(id,subdomain,timezone,timeout,offline,hash_config,hash_points) VALUES(0,'subdomain','UTC',5,0,'hash_config','hash_points');
CREATE TRIGGER `config_insert_zero`
BEFORE INSERT ON `config`
FOR EACH ROW
BEGIN
-- SET NEW.id=0;
NEW.id=OLD.id;
END;
CREATE TRIGGER `config_update_zero`
BEFORE UPDATE ON `config`
FOR EACH ROW
BEGIN
-- SET NEW.id=0;
NEW.id=OLD.id;
END;
Run Code Online (Sandbox Code Playgroud)
CL.*_*CL. 18
在一般情况下,要限制表中的行数,必须阻止任何进一步的插入.在SQLite中,这是通过RAISE()完成的:
CREATE TRIGGER config_no_insert
BEFORE INSERT ON config
WHEN (SELECT COUNT(*) FROM config) >= 1 -- limit here
BEGIN
SELECT RAISE(FAIL, 'only one row!');
END;
Run Code Online (Sandbox Code Playgroud)
但是,如果限制为1,则可以简单地将主键限制为固定值:
CREATE TABLE config (
id INTEGER PRIMARY KEY CHECK (id = 0),
[...]
);
Run Code Online (Sandbox Code Playgroud)
您可能要考虑的一个想法是使它看起来像表只有一行。实际上,您保留了所有先前的行,因为有一天您很可能希望保留所有过去值的历史记录。
由于只有一行,因此实际上不需要ID列,其目的是将每一行与所有其他行唯一区分开。但是,您确实需要一个时间戳,用于标识“一行”,该行将是写入表的最新行。
CREATE TABLE `config_history` (
`created` timestamp default current_timestamp,
`subdomain` VARCHAR(45) NOT NULL,
`timezone` CHAR(3) NOT NULL,
`timeout` TINYINT NOT NULL,
`offline` TINYINT NOT NULL,
`hash_config` CHAR(32) NOT NULL,
`hash_points` CHAR(32) NOT NULL,
PRIMARY KEY (`created`)
);
Run Code Online (Sandbox Code Playgroud)
由于通常只对最后写入的行(最新版本)感兴趣,因此查询将选择具有最新创建日期的行:
select ch.created effective_date, ch.subdomain, ch.timezone, ch.timeout,
ch.offline, ch.hash_config, ch.hash_points
from config_history ch
where ch.created =(
select max( created )
from config_history );
Run Code Online (Sandbox Code Playgroud)
create view config as在此查询前放置一个,您将拥有一个视图,该视图仅从表中选择一行,即最新的。对视图的任何查询都返回一行:
select *
from config;
Run Code Online (Sandbox Code Playgroud)
一个instead of对视图触发器可以更新转换为插入-你实际上并不想改变值,只写一个新行的新值。然后,这成为新的“当前”行。
现在,您的表似乎只有一行,但是您也保留了对该行过去所做的所有更改的完整历史记录。
| 归档时间: |
|
| 查看次数: |
4099 次 |
| 最近记录: |