Можете ли вы установить значение по умолчанию для столбца на основе расчетов предыдущих двух столбцов в SQLite? - PullRequest
0 голосов
/ 01 января 2019

У меня есть таблица в SQLite, где я хотел бы установить значение 3-го столбца на основе входного значения первых двух столбцов.

Поддерживает ли 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] не является постоянным)

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Как ясно указывает на сообщение об ошибке «значение по умолчанию столбца [GUARANTEED_YIELD] не является константой», вы не можете использовать переменные в выражении по умолчанию.

Один из способов добиться того, чего вы хотите, - это сделать послетриггер вставки, который обновляет столбец, когда он был вставлен как нулевойЭто, однако, требует, чтобы столбец не был объявлен не пустым, иначе 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 - это целое число, но ваше выражение по умолчанию, скорее всего, дает нецелые значения.Вы можете потерять что-то из-за необходимого округления.Я не уверен, является ли это преднамеренным.


Приложение:

Глядя на комментарии к вашему вопросу, я не уверен, хотите ли вы просто использовать значение по умолчанию - то есть значениеиз guaranteed_yield должно иметь значение выражения, если никакое другое значение явно не задано в INSERT, но для него возможно иметь другие (не нулевые) значения либо из INSERT, либо из последующего UPDATE- или если вы хотите, чтобы это был вычисляемый столбец, он всегда имеет значение, которое дает выражение.В последнем случае: я второй комментаторов.Это потенциально опасная вещь в отношении несоответствий.Желательно использовать выражение в ваших запросах или создать представление.

0 голосов
/ 01 января 2019

Это не поддерживается в SQLite.

Документация CREATE TABLE гласит:

Явное предложение DEFAULT может указывать, что значением по умолчанию является NULL,строковая константа, константа BLOB-объекта, число со знаком или любое выражение константы, заключенное в скобки.

Кроме того, в документе определяется понятие константа :

Для целей предложения DEFAULT выражение считается константой, если оно не содержит подзапросов, ссылок на столбцы или таблицы, связанных параметров или строковых литералов, заключенных в двойные кавычки вместо одинарных кавычек.

Это исключает ссылки на другие столбцы.

Другие возможные подходы в вашем случае использования:

  • вычисляет значение динамически в ваших запросах DML (UPDATE иINSERT)
  • использовать триггер для обеспечения динамического значения по умолчанию для операций DML
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...