[英]Can you set default value of a column based on the calculations of previous two columns in 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 integer not null default (insurance_pct/100 * historical_yield)
)
當我運行以上語句時,我看到以下錯誤。
查詢執行失敗
原因:
SQL錯誤[1]:[SQLITE_ERROR] SQL錯誤或缺少數據庫(列[GUARANTEED_YIELD]的默認值不是常數)
SQLite不支持此功能。
顯式的DEFAULT子句可以指定默認值為NULL,字符串常量,blob常量,帶符號的數字或括號中包含的任何常量表達式。
此外,文檔定義了常量表達式的概念:
就DEFAULT子句而言,如果表達式不包含用雙引號而不是單引號引起來的子查詢,列或表引用,綁定參數或字符串文字,則該表達式被視為常量。
也就是說,這不包括對其他列的引用。
您的用例中的其他可能方法:
由於錯誤消息“ [GUARANTEED_YIELD]列的默認值不恆定”明確指出,因此不能在默認表達式中使用變量。
實現所需目標的一種方法是,在將列插入為null時,創建一個after after觸發器,以更新該列。 但是,這要求該列不能聲明為非null,否則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;
我注意到的另一件事: guaranteed_yield
是一個整數,但是您的默認表達式很可能會產生非整數值。 由於需要四舍五入,您可能會丟失一些東西。 我不確定這是否是故意的。
附錄:
查看問題的注釋,我不確定您是否只想要默認值-即,如果在INSERT
未明確給出其他值,則guaranteed_yield
的值應具有表達式的值,但是有可能具有來自INSERT
或后續UPDATE
其他(非null)值-或如果您打算將其作為計算列,則始終具有表達式給出的值。 在后一種情況下:我將其他評論員放在第二位。 關於不一致,這是潛在的危險。 最好在查詢中使用該表達式或創建一個視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.