Как установить значение по умолчанию при вставке на пустой выбор в SQLite - PullRequest
0 голосов
/ 29 октября 2019

Я веду запись всех изменений в таблице данных, так что в таблице хранится старое значение и новое значение любого внесенного изменения. Я использую insert с select, чтобы получить старое значение. Это работает хорошо, но не учитывает значение по умолчанию таблиц записей изменений для старого значения.

схема

CREATE TABLE IF NOT EXISTS rovers (
    name TEXT PRIMARY KEY,
    location TEXT
);

CREATE TABLE IF NOT EXISTS change_record (
    rover TEXT NOT NULL,
    key TEXT NOT NULL,
    timestamp TEXT NOT NULL,

    oldValue TEXT DEFAULT "",
    newValue TEXT NOT NULL,

    PRIMARY KEY(rover, key, timestamp)
);

При добавлении или обновлении используется следующее:

INSERT INTO change_record (rover, timestamp, key, oldValue, newValue) VALUES (
    "curiosity"
    "2019-10-29T09:42:32.865Z",
    "location",
    (SELECT location FROM rovers WHERE name = "curiosity"),
    "surface"
);
INSERT OR REPLACE INTO rovers (name, location) VALUES ("curiosity", "surface")

Если для name = "curiosity" уже есть строка, то oldValue правильно установлена ​​в change_record, но если ровер не существует, то oldValue устанавливается на NULL.

Следующее работает, но мне кажется неэффективным (требуется два выбора):

INSERT INTO change_record (rover, timestamp, key, oldValue, newValue) VALUES (
    "curiosity"
    "2019-10-29T09:42:32.865Z",
    "location",
    CASE
        WHEN EXISTS (SELECT location FROM rovers WHERE name = "curiosity") THEN
            (SELECT location FROM rovers WHERE name = "curiosity"),
        ELSE
            ''
    END,
    "surface"
);

Возможно ли сделать это без блока CASE, с каким-то образом IFNULL? Кроме того, возможно ли использовать значение по умолчанию, определенное в CREATE TABLE, без необходимости дублировать его?

1 Ответ

1 голос
/ 29 октября 2019

Если вы хотите избежать 2 SELECT s внутри запроса INSERT, вы можете использовать CTE, который будет возвращать либо значение столбца location, если оно существуетили NULL, если он не существует. Затем используйте COALESCE(), чтобы изменить значение NULL на '':

WITH cte AS (SELECT location FROM rovers WHERE name = 'curiosity')
INSERT INTO change_record (rover, key, timestamp, oldValue, newValue) VALUES (
    'curiosity',
    '2019-10-29T09:42:32.865Z',
    'location',
    COALESCE((SELECT location FROM cte), ''),
    'surface'
);

Я сохранил порядок столбцов так же, как ваш код, но если это не опечаткаЯ думаю, что key и timestamp следует поменять местами, потому что, как они есть, они получат значения: '2019-10-29T09:42:32.865Z' и 'location' соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...