SQLite变量CHECK约束

时间:2017-01-10 11:00:58

标签: sql sqlite

我在染色体上有染色体(具有长度的物体)和带有区域(例如基因)的表格(具有定义为两个整数的范围的对象 - 位置开始和位置结束)。我想禁止插入坐标大于特定染色体长度的数据库区域。

在SQLite中可以吗? 如果不是可以在任何其他SQL系统中(最好是免费的)?

DROP TABLE IF EXISTS chromosomes;
CREATE TABLE chromosomes
  (
     chromosome_id INTEGER UNIQUE NOT NULL CHECK(TYPEOF(chromosome_id) = 'integer'),
     name          VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(name) = 'text'),
     length        INTEGER NOT NULL CHECK(TYPEOF(length) = 'integer' AND length > 0),
     PRIMARY KEY (chromosome_id)
  );


DROP TABLE IF EXISTS genes;
CREATE TABLE genes
  (
     gene_id           INTEGER UNIQUE NOT NULL CHECK(TYPEOF(gene_id) = 'integer'),
     symbol            VARCHAR NOT NULL CHECK(TYPEOF(symbol) = 'text'),
     refseq_id         VARCHAR NOT NULL CHECK(TYPEOF(refseq_id) = 'text'),
     chromosome_id     INTEGER NOT NULL CHECK(TYPEOF(chromosome_id) = 'integer'),
     start             INTEGER NOT NULL CHECK(TYPEOF(start) = 'integer' AND start > 0 AND start < end),
     end               INTEGER NOT NULL CHECK(TYPEOF(end) = 'integer' AND end > 0 AND end > start),
     external_db_link  VARCHAR NOT NULL CHECK(TYPEOF(external_db_link) = 'text'),
     PRIMARY KEY (gene_id)                   
     FOREIGN KEY (chromosome_id) REFERENCES chromosomes(chromosome_id)
  );

1 个答案:

答案 0 :(得分:1)

此类约束在任何数据库中都不能轻松。通常,这将使用触发器来处理。问题是它是两个表之间的约束,但它不使用相等。

SQLite以及其他数据库中都提供了触发器。

一种解决方法是使用用户定义的函数进行检查约束。该函数可以查找chromosomes表并在check约束中使用。 SQLite实际上没有用户定义的函数。一个支持这个的数据库是Postgres。

另一种选择是将所有数据修改包装在存储过程中(这往往是我设计系统的方式)。然后存储过程可以执行所需的所有检查。