Существует ли идиоматический способ обновления только определенных полей в PostgreSQL?

#sql #database #postgresql

Вопрос:

Есть ли какой-нибудь хороший способ получить UPDATE запрос с дополнительными данными? то, что у меня есть сейчас, — это:

  • Пример Author
 {
    "id": "203ede72-45af-4029-8055-e1c43656d42d",
    "first_name": "Willdon",
    "last_name": "Surgey"
},
 
  • Функция postgres для обновления автора
 -- UPDATE
create or replace
function update_author(target_id uuid, i_first_name varchar(50), i_last_name varchar(50))
returns json
language plpgsql
as
$
declare inserted_author authors%rowtype;
begin
     update authors a
     set first_name = i_first_name,
          last_name = i_last_name
     where a.id = target_id
     returning * into inserted_author;

return row_to_json(inserted_author);
end;
$;
 

Теперь, если я сделаю PUT запрос по адресу /author/203ede72-45af-4029-8055-e1c43656d42d с телом

 {
    "last_name": "Smith"
}
 

Это становится

 {
    "id": "203ede72-45af-4029-8055-e1c43656d42d",
    "first_name": "",
    "last_name": "Smith"
}
 

Я хочу, чтобы он сохранился first_name , если только last_name будет поставлен

Комментарии:

1. first_name = coalesce(i_first_name, first_name) это один из способов, но я подозреваю, что , как и Oracle, он добавит в журнал предварительной записи тот факт, что first_name ему будет присвоено текущее значение, когда i_first_name is null , что является пустой тратой времени. В зависимости от ваших тенденций к совершенству , чтобы избежать этой потери, вы должны выполнить одно из двух различных инструкций обновления в зависимости от i_first_name .

2. к сожалению, он принимает i_first_name как пустую строку и присваивает пустую строку

3. Используйте case тогда. Поскольку существует различие между нулевой и пустой строкой, вы можете перечислить, что вы хотите сделать для обеих.

Ответ №1:

В итоге я сделал то, что изначально запросил полный author объект из базы данных, а затем использовал golang Unmarshal его для выборочного изменения свойств, а затем передал полные данные в функцию postgres.

ПРИМЕЧАНИЕ. Если вы используете этот обходной путь, обязательно выполните какую-либо проверку, чтобы ваши пользователи не могли взломать вашу базу данных с помощью запроса, такого как PUT /author/f3ef41a5-fe1e-4180-92bf-8b87e879211d

 {
    "id": "g3ef41a5-fe1e-4180-92bf-8b87e879211d",
    "last_name": "Smith"
}
 

обратите внимание, что первая буква UUID была изменена, это может привести к поломке.