Как обновить поля при вставке с помощью триггера

Я создавал триггеры в Oracle и работал с ними в течение многих лет, однако я не могу понять, как обновить поле при вставке данных в базу данных sqlite.

Все, что я хочу сделать, это создать триггер, который автоматически вставляет текущий DateTime в столбец базы данных sqlite с именем createdDate для ЛЮБОЙ вставленной записи.

Как лучше всего этого добиться?

Ниже описано то, что я безуспешно пытался.

CREATE TRIGGER outputLogDB_Created_Trig
    BEFORE INSERT
        ON outputLog
      WHEN NEW.createdDate IS NULL
BEGIN
    SELECT CASE WHEN NEW.createdDate IS NULL THEN NEW.createdDate = datetime('now', 'localtime') END;
END;

Вышесказанное является почти копией того, как я бы реализовал свои триггеры в Oracle с некоторыми изменениями, конечно, для sqlite. Логика в основном идентична.

Что мне не хватает?

Позднее редактирование - я могу заставить его работать, если вместо этого использую AFTER INSERT, а не FOR EACH ROW

CREATE TRIGGER outputLog_Created_Trig
     AFTER INSERT
        ON outputLog
      WHEN New.createdDate IS NULL
BEGIN
    UPDATE outputLog
       SET createdDate = datetime('now', 'localtime') 
     WHERE outputLog_ID = New.rowid;
END;

Но почему я не могу просто вставить запись с новым значением во время ее вставки? Могу ли я получить это ТОЛЬКО с помощью обновления ПОСЛЕ того, как я уже вставил запись?

Проблема, с которой я столкнулся, заключается в том, что я хотел бы иметь ограничение NOT NULL для столбца createdDate. Возможно, я просто привык к тому, как много лет делал это в Oracle? Я понимаю, что триггер «должен» заботиться о любой записи и заставлять это поле НИКОГДА не быть NULL. Просто НЕЛЬЗЯ добавить ограничение по какой-то причине меня беспокоит. Мне нужно избавиться от этого беспокойства?


person Code Novice    schedule 27.02.2019    source источник
comment
Я вижу много примеров триггеров sqlite, использующих FOR ALL ROWS, однако я не верю, что мне это нужно, поскольку я не собираюсь иметь дело с коллекцией строк ... Мне нужен только триггер, чтобы действовать для каждой отдельной вставленной строки ... независимо от того, вставляется ли это 1 строка или 100 строк. Мне не нужно было бы перебирать 1 строку при каждой вставке отдельной строки. Хмммм ...   -  person Code Novice    schedule 27.02.2019
comment
Просто используйте значение по умолчанию для столбца в определении таблицы.   -  person Shawn    schedule 27.02.2019
comment
Ну ... вот и все. Почти слишком просто. DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime') )   -  person Code Novice    schedule 28.02.2019


Ответы (1)


Спасибо Шону, который указал мне на простое простое решение моей проблемы. Все, что требуется в базе данных SQLite для вставки текущей даты и времени для каждой вставляемой записи, - это установить значение DEFAULT в этом столбце на CURRENT_TIMESTAMP.

Поскольку мне нужна метка времени в моем собственном местном времени, см. Ниже сценарий создания таблицы, который является решением моей проблемы.

CREATE TABLE outputLog (
    outputLog_ID INTEGER  PRIMARY KEY ASC ON CONFLICT ROLLBACK AUTOINCREMENT
                          NOT NULL ON CONFLICT ROLLBACK,
    outputLog    TEXT,
    created      DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime') ) 
                          NOT NULL )
;
person Code Novice    schedule 27.02.2019