SQLite变量检查约束

j91ykkif  于 2022-11-15  发布在  SQLite
关注(0)|答案(2)|浏览(185)

我有染色体表(有长度的对象)和染色体上区域(例如基因)的表(对象的范围定义为两个整数-位置开始和位置结束)。我想禁止插入坐标大于特定染色体长度的数据库区域。
这在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)
  );
7rfyedvj

7rfyedvj1#

这种类型的约束在任何数据库中都不“容易”可用。通常,这将使用触发器来处理。问题是它是两个表之间的约束,但它不使用相等。
触发器在SQLite和其他数据库中都可用。
一种解决办法是使用用户定义函数的检查约束。该函数可以查找chromosomes表,并在check约束中使用。SQLite实际上并没有用户定义的函数。支持这一点的一个数据库是postgres。
另一种选择是将所有数据修改 Package 在存储过程中(这往往是我设计系统的方式)。然后,存储过程可以执行所需的所有检查。

v64noz0r

v64noz0r2#

冗余--使用外键将‘LENGTH’引入子表。那么您的CHECK约束就可以引用它了。

相关问题