Я думаю, у вас есть 2 варианта. Первый уродлив и, вероятно, медленнее, но, насколько я знаю, это стандартный SQL и широко поддерживается. Второй не является стандартным, но поддерживается SQLite начиная с версии 3.24.0.
Встроенный выбор
Исходя из этого ответа , вы можете сделать что-то вроде
INSERT OR REPLACE INTO MyTableName
VALUES (
'example_id',
COALESCE(100, (SELECT COLUMN_NAME_B from MyTableName WHERE COLUMN_NAME_A = 'example_id')),
COALESCE(1.0, (SELECT COLUMN_NAME_C from MyTableName WHERE COLUMN_NAME_A = 'example_id'))
);
Это довольно просто, но немного уродливо и потенциально медленно. Чем больше у вас столбцов, тем больше встроенных выделений вам нужно сделать (на самом деле они нужны только для столбцов с потенциальными нулевыми значениями, но все же), и чем больше строк, тем больше времени занимает выбор.
Upsert
Но если вы используете SQLite версии 3.24.0 или новее, вы можете использовать так называемый upsert синтаксис
INSERT INTO MyTableName
VALUES ('example_id', 100, 1.0)
ON CONFLICT(COLUMN_NAME_A) DO UPDATE SET
COLUMN_NAME_B = COALESCE(EXCLUDED.COLUMN_NAME_B, COLUMN_NAME_B),
COLUMN_NAME_C = COALESCE(EXCLUDED.COLUMN_NAME_C, COLUMN_NAME_C);
где EXCLUDED.COLUMN_NAME_ ссылается на новое значение, которое будет вставлено (которое «исключено», пока мы не разрешим конфликт).