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

В моем приложении для Android есть база данных SQLite, которую я хотел бы обновить. Обновление требует изменения типа данных с INT на FLOAT. Я понимаю, что для достижения этого в SQLite нужно создать новую таблицу, скопировать данные, а затем заменить старую таблицу новой. Копирование будет выполнено следующим образом:

INSERT INTO newTable SELECT * FROM oldTable

, где целочисленные значения будут удобно преобразованы в значения с плавающей запятой.

Теперь существует проблема, заключающаяся в том, что другой, ранее необязательный столбец теперь равен ´NOTNULL´, но имеет значение по умолчанию. Я хотел бы, чтобы все экземпляры NULL были заменены значениями по умолчанию в рамках вышеуказанного процесса, используя следующую инструкцию:

INSERT INTO newTable SELECT * FROM oldTable ON CONFLICT REPLACE

или, для полноты, в Android / Kotlin:

db.execSQL(“INSERT INTO newTable SELECT * FROM oldTable ON CONFLICT REPLACE”)

Это дает мне синтаксическую ошибку, и я не смог найти подходящий пример в другом месте. Каков будет правильный синтаксис для достижения этого - и то, что я пытаюсь сделать, даже возможно?

1 Ответ

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

Если вы посмотрите на документацию для INSERT, вы увидите, что это должно быть INSERT OR REPLACE ..., и, да, это сработает, чтобы заменить пустые значения в столбце, отличном от нуля, назначение по умолчанию.

Заменить документацию по разрешению конфликтов :

При возникновении нарушения ограничения UNIQUE или PRIMARY KEY алгоритм REPLACE удаляет ранее существующие строки, которые являютсявызывает нарушение ограничения до вставки или обновления текущей строки, и команда продолжает выполняться в обычном режиме. Если происходит нарушение ограничения NOT NULL, разрешение конфликта REPLACE заменяет значение NULL значением по умолчанию для этого столбца , или если столбец не имеет значения по умолчанию, то используется алгоритм ABORT. Если возникает ограничение CHECK или ограничение внешнего ключа, алгоритм разрешения конфликта REPLACE работает как ABORT.


Пример:

sqlite> CREATE TABLE foo(x, y NOT NULL DEFAULT 1);
sqlite> INSERT INTO foo(x,y) VALUES ('a', null);
Error: NOT NULL constraint failed: foo.y
sqlite> INSERT OR REPLACE INTO foo(x,y) VALUES ('a', null);
sqlite> SELECT * FROM foo;
x           y         
----------  ----------
a           1         
...