簡體   English   中英

您可以根據SQLite中前兩列的計算設置列的默認值嗎?

[英]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不支持此功能。

CREATE TABLE文檔指出:

顯式的DEFAULT子句可以指定默認值為NULL,字符串常量,blob常量,帶符號的數字或括號中包含的任何常量表達式。

此外,文檔定義了常量表達式的概念:

就DEFAULT子句而言,如果表達式不包含用雙引號而不是單引號引起來的子查詢,列或表引用,綁定參數或字符串文字,則該表達式被視為常量。

也就是說,這不包括對其他列的引用。

您的用例中的其他可能方法:

  • 在DML查詢中動態計算值(UPDATE和INSERT)
  • 使用觸發器提供DML操作的動態默認值

由於錯誤消息“ [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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM