2015-10-13 12 views
5

Bir tabloyu yalnızca bir satır olacak şekilde nasıl uygulayabilirim? Denediğim şey aşağıda. UPDATE tetikleyici işe yarayabilir, ancak CREATE tetikleyici kesinlikle olmaz. CREATE için SET'u kullanmak istiyorum, ancak SET SQLite tarafından desteklenmiyor.SQLite tablosunun yalnızca bir satır var olduğundan emin olun

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; 

cevap

7

Genel durumda, bir tablodaki satır sayısını sınırlamak için, daha fazla ek eklemeniz gerekir. SQLite, bu RAISE() ile yapılır:

CREATE TABLE config (
    id INTEGER PRIMARY KEY CHECK (id = 0), 
    [...] 
); 
+0

İkinci çözümünüzü seviyorum! 'RAISE' ile ilgili açıklama için teşekkürler. İkinci çözümünüzü vererek bir tetikleyici kullanmam gerekmeyeceği için, UPDATE kısıtlaması nasıl uygulanacak? Hepsini aç Hepsini kapa Bu Sayfada Belirtiler Yapılandırma yapılandırma CREATE TRIGGER config_update_zero BEGIN NEW.id = OLD.id; END; NEW.id = OLD.id; '? – user1032531

+0

UPDATE tetikleyicisine ne için ihtiyacınız var? –

+0

'UPDATE config SET id = 2' izin vermek istemiyor. İkinci çözümünüz bunu engelliyor ve sadece bir tetikleyici ile nasıl yapıldığını merak ediyordu. – user1032531

1

Bir fikir isteyebilirsiniz: Limit biriyse

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; 

Ancak, bunun yerine basitçe sabit bir tutar olarak birincil anahtar sınırlamak olabilir Göz önünde bulundurulması, tablodaki tek satırın olduğu gibi görünmesini sağlamaktır. Gerçekte, önceki tüm satırları tutarsınız, çünkü bir gün tüm geçmiş değerlerin geçmişini korumak istersiniz.

Sadece bir satır olduğu için, bir ID sütununa gerek yoktur, bunun amacı her satırı diğerlerinden ayırmaktır. Bununla birlikte, tabloya yazılan en son satır olacak "bir satır" tanımlamak için kullanılacak bir zaman damgası gerekir.

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); 

bu sorgu önünde bir create view config as koyun:

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`) 
); 

yazılı sadece son satır (son sürüm) normalde ilgilenen olduğundan, sorgu son oluşturulma tarihi ile satırı seçer ve tablodan en son bir satır seçen bir görünümünüz var. aslında bir değeri değiştirmek istemiyoruz, sadece yeni değerlerle yeni bir satır yazma -

select * 
from config; 

Eklemeler Güncellenmesine dönüştürebilirsiniz görünümde bir instead of tetik: view karşı herhangi bir sorgu bir satır döndürür . Bu daha sonra yeni "geçerli" satır olur.

Artık yalnızca bir satır içeren bir tablo var gibi görünüyor, ancak aynı zamanda bu sıraya yapılan tüm geçmiş değişikliklerin geçmişini de koruyorsunuz.

İlgili konular