Android 能否根据SQLite中前两列的计算设置列的默认值?
我在SQLite中有一个表,我想根据前两列的输入值设置第三列的值 SQLite是否支持列的默认值中的表达式Android 能否根据SQLite中前两列的计算设置列的默认值?,android,sql,database,sqlite,Android,Sql,Database,Sqlite,我在SQLite中有一个表,我想根据前两列的输入值设置第三列的值 SQLite是否支持列的默认值中的表达式 create table contract( id primary key autoincrement, insurance_pct integer not null default 0, historical_yield integer not null default 0, guaranteed_yield intege
create table contract(
id primary key autoincrement,
insurance_pct integer not null default 0,
historical_yield integer not null default 0,
guaranteed_yield integer not null default (insurance_pct/100 * historical_yield)
)
当我运行上述语句时,我看到以下错误
查询执行失败
原因:
SQL错误[1]:[SQLITE_Error]SQL错误或缺少数据库(列[Guaranted_YIELD]的默认值不是常量)
SQLite不支持这一点 各国: 显式DEFAULT子句可以指定默认值为NULL、字符串常量、blob常量、有符号数字或括号中包含的任何常量表达式 此外,本文件定义了常量表达式的概念: 对于DEFAULT子句,如果表达式不包含子查询、列或表引用、绑定参数或用双引号而不是单引号括起来的字符串文字,则该表达式被视为常量 这就排除了对其他列的引用 用例中的其他可能方法:
- 动态计算DML查询中的值(更新和插入)
- 使用触发器提供DML操作的动态默认值
INSERT
将失败。所以你也必须在更新前触发器中检查
CREATE TABLE contract
(id integer PRIMARY KEY
AUTOINCREMENT,
insurance_pct integer
NOT NULL
DEFAULT 0,
historical_yield integer
NOT NULL
DEFAULT 0,
guaranteed_yield integer
NULL
DEFAULT NULL);
CREATE TRIGGER contract_ai
AFTER INSERT
ON contract
FOR EACH ROW
WHEN (new.guaranteed_yield IS NULL)
BEGIN
UPDATE contract
SET guaranteed_yield = insurance_pct / 100 * historical_yield
WHERE id = new.id;
END;
CREATE TRIGGER contract_bu
BEFORE UPDATE
ON contract
FOR EACH ROW
WHEN (new.guaranteed_yield IS NULL)
BEGIN
SELECT raise(FAIL, 'NOT NULL constraint failed: contract.guaranteed_yield');
END;
我注意到另一件事:保证收益率
是一个整数,但您的默认表达式很可能生成非整数值。由于所需的舍入,您可能会丢失某些内容。我不确定这是否是故意的
增编:
查看对您的问题的评论,我不确定您是否只想要一个默认值,即
保证收益率
的值应该具有表达式的值,如果在插入
中没有明确给出其他值,但它可能具有其他值(非空)来自插入
或后续更新
的值,或者如果您打算将其作为计算列,则始终具有表达式给出的值。在后一种情况下:我支持其他评论者。对于不一致性,这是一个潜在的危险因素。最好在查询中使用表达式或创建视图。sqlite手册中的“创建表”文档不清楚吗?它确实支持默认值的表达式,但我很确定无法引用插入行的其他列。在这种情况下,因为它非常简单,所以在需要时(可能在视图中)只需动态计算值,而不是使用列。是的,我同意这里的计算非常简单和直接,但这里的要点是代码越少,错误就越少。为什么要在你的代码中写一些东西,而供应商的软件可以在不引入任何bug的情况下动态地为你做呢?这是一个与SQLite特性相关的有效问题,不知道为什么会被否决。虽然我很欣赏随答案提供的反馈、评论和逻辑,但这只是开发人员希望将业务逻辑放在何处的品味问题。@user2325154::这当然是一个有效的问题,但我不同意创建一个列来存储“业务逻辑”的“优势”。当业务逻辑在某个时刻发生变化时会发生什么?留下的列中充满了无用的、潜在危险的数据——这些数据无法更改,因为它们“硬连接”到数据库。您已经准备用一个简单的SQL“SELECT”语句查询数据库了。将计算添加到语句中不应引入任何您的建议无法引入的错误。@user2325154:另请参阅我的附录。