Я пытаюсь записать обновления поля в таблицу SQLite.Я уже могу войти INSERTs , используя что-то вроде этого:
CREATE TRIGGER _test7_INSERT AFTER INSERT ON test7
BEGIN
INSERT INTO ChangeLog (rid, field, value, tms)
SELECT *,CAST((julianday('now') - 2440587.5)*86400000 AS INTEGER)
FROM (VALUES
(new.rowid, 'field1', new.field1),
(new.rowid, 'field2', new.field2),
(new.rowid, 'field3', new.field3)
) sub;
END;
Это, очевидно, использует анонимные значения, по которым я не смог найти конкретную документацию, но этоКажется, работает при создании статической таблицы, которую я могу выбрать для вставки в таблицу журнала.
Однако для обновлений я хочу регистрировать только те поля, которые действительно меняются, поэтому, например, если в таблице было 20 полейи только 1 изменилось из-за обновления. Я бы хотел, чтобы в таблицу изменений была добавлена только 1 строка, а не 20. У меня есть триггер, который выглядит следующим образом:
CREATE TRIGGER _test7_UPDATE AFTER UPDATE on test7
BEGIN
INSERT INTO ChangeLog (rid, field, value, tms)
SELECT "" AS rid,
":1" AS field,
":2" AS value,
CAST((julianday('now') - 2440587.5)*86400000 AS INTEGER) AS tms
FROM (VALUES
(old.rowid, 'field1', new.field1, new.field1=old.field1),
(old.rowid, 'field2', new.field2, new.field2=old.field2),
(old.rowid, 'field3', new.field3, new.field3=old.field3)
) sub
WHERE ":4"=1;
END;
Но при выполнении операции ничего не вставляетсяОбновить!Если я удаляю дополнительное поле сравнения и удаляю предложение "WHERE", я вижу добавление трех строк, но вместо добавляемых rid
, field
и value
я вижу буквальные значения "", ":1 "и": 2 ".Я не нашел много документации по этим пронумерованным параметрам - на странице языка SQLite в разделе «Параметры» попутно упоминается о них, но очень мало о них говорится - и даже не объясняется, почему": 1" - это на самом деле второй параметр, а "" - первый!Я должен добавить, что я экспериментировал с использованием очень похожего SELECT вне триггера, помещая постоянные значения в таблицу VALUES, и это прекрасно работает!В частности:
SELECT "" AS a, ":1" AS b, ":2" AS c, ":3" AS d
FROM (VALUES
(11,22,33,44),
(111,122,133,144),
(211,222,233,244)
) sub;
возвращает таблицу, содержащую буквенные значения, столбцы, помеченные как «a», «b», «c» и «d».Но та же базовая структура в триггере возвращает буквальные строки с двоеточиями вместо фактических ожидаемых значений.
У меня была яркая идея создать временную таблицу с дополнительным полем, выделить все в нее, затем выбрать все, кромесравнение в реальной таблице журнала.Это не работает, так как CREATE не поддерживается в триггере)
Я также попытался создать ChangeLog, чтобы иметь дополнительное поле для хранения пятого поля в сравнении (например, new.fieldx = old.fieldx), но когда яиспользуйте предложение WHERE, чтобы выбрать только те поля, которые изменились, я возвращаюсь к тому, что ничего не вставляется снова.
Есть ли какой-то другой способ, которым я должен идти об этом, или я делаю что-то не так с тем, как я обращаюсь с позиционными параметрами?
ОБНОВЛЕНИЕ : я былэкспериментировали и обнаружили, что при некоторых обстоятельствах позиционные параметры действительно имеют значения, но они довольно бессмысленные:
DB Fiddle
В частности, поле ""
возвращаетзначение параметра second , а поле ":1"
возвращает значение параметра четвертого .Зачем?Как мне сослаться на первый и третий параметр?
ОБНОВЛЕНИЕ 2 : После того, как вы поиграете с этим немного больше, кажется, что "", ": 1", ": 2"и т. д. параметры работают нормально, если в таблице VALUES есть только постоянные значения.Любые фактические значения, которые я вставляю, например, из новых, старых и т. Д. - столбцы, которые мне действительно нужны - полностью игнорируются, как будто этих столбцов даже нет!