SQLite 中的校验位约束

Check digit constraint in SQLite

我正在尝试为 id(长度为 5 位)创建约束,其中第 5 位是值的最后一位(1 x d1 + 3 x d2 + 1 x d3 + 3 x d4) .例如,如果 id 的前四个字符是 1234,那么第五位是 (1x1+3x2+1x3+3x4) = 22 的最后一位,结果 d5 = 2 的校验位。因此 id = 12342。

这是我的代码;

CREATE TABLE GameLicense_16 (
title TEXT,
release_year INTEGER,
platform TEXT,
license_id INTEGER PRIMARY KEY
CHECK (LENGTH(license_id) == 5)
CHECK ((substr (license_id, 5, 1)) = substr (CAST ((substr (license_id, 1, 1) BETWEEN 0 AND 9) 
AS int) +
3* CAST ((substr (license_id, 2, 1) BETWEEN 0 AND 9) AS int) +
1* CAST ((substr (license_id, 3, 1) BETWEEN 0 AND 9) AS int) +
3* CAST ((substr (license_id, 4, 1) BETWEEN 0 AND 9) AS int),2,1))
);

但是当我尝试用12342的license id测试它时,它给了我约束失败的错误信息,这意味着某处计算错误但我无法弄清楚。

由于您将 license_id 定义为 INTEGER PRIMARY KEY,因此无需通过使用 ... BETWEEN 0 AND 9.[=22 检查每个字符来检查您插入的值是否为整数=] 事实上,这是 SQLite 强制类型检查的唯一情况,因此您可以确定非整数值将被拒绝。
同样在您的代码中,您混合了布尔表达式和 substring() 这没有意义。

只关注检查约束规则,可以这样做:

CREATE TABLE GameLicense_16 (
  title TEXT,
  release_year INTEGER,
  platform TEXT,
  license_id INTEGER PRIMARY KEY
  CHECK (LENGTH(license_id) == 5)
  CHECK (
    SUBSTR(license_id, 5, 1) + 0 = ( 
      SUBSTR(license_id, 1, 1) + 3 * SUBSTR(license_id, 2, 1) +
      SUBSTR(license_id, 3, 1) + 3 * SUBSTR(license_id, 4, 1)
    ) % 10
  )  
);

参见demo