Вы можете проверить, существует ли он в массиве, прежде чем добавлять его:
UPDATE book_shelf
SET book_id = CASE WHEN CAST(:bookID AS BIGINT) = ANY(book_id) THEN book_id ELSE ARRAY_APPEND(book_id, CAST(:bookID AS BIGINT)) END, updated_at = now()
WHERE user_id = :userID AND shelf_name = :shelfName
Конечно, если updated_at
следует устанавливать только в том случае, если book_id
действительно обновлено, тогда поставьте проверку в ГДЕпункт, поэтому он не обновляется без необходимости:
UPDATE book_shelf
SET book_id = ARRAY_APPEND(book_id, CAST(:bookID AS BIGINT)), updated_at = now()
WHERE user_id = :userID
AND shelf_name = :shelfName
AND NOT CAST(:bookID AS BIGINT) = ANY(book_id)