#sql #sqlite #sql-update #prepared-statement #sql-insert
#sql #sqlite #sql-обновление #подготовленный оператор #sql-вставка
Вопрос:
Я вставляю или обновляю строку в базу данных Sqlite с database/sql
помощью пакета Go. У меня есть много столбцов для обновления (около 16 столбцов одного элемента). Для использования UPSERT
мне нужно дублировать все ?
и параметры полей данных оператора, поэтому общее количество параметров оператора составляет около 32:
// Save item to database using transaction
func (item *Item) Save(tx *sql.Tx) error {
stmt, err := tx.Prepare(`INSERT INTO "items" (
id, data1, data2, ..., dataN
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id)
DO UPDATE SET data1 = ?, data2 = ?, ..., dataN = ?`) // set same values as insert
// skip checking errors, defer close(), etc
_, err := stmt.Exec(item.id,
item.data1, item.data2, /*...*/ item.dataN,
item.data1, item.data2, /*...*/ item.dataN) // duplicates
}
Можно ли избежать дублирования и ссылаться на одни и те же параметры из INSERT
и DO UPDATE
?
Ответ №1:
В SQLite вы можете использовать псевдотаблицу excluded
в DO UPDATE
предложении для ссылки на значения, которые были бы вставлены в противном случае:
INSERT INTO "items" (id, data1, data2, data3)
VALUES (?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
data1 = excluded.data1,
data2 = excluded.data2,
data3 = excluded.data3