Great answers Simon/fml2.
Typically the best way to implement DB logic is on the DB
(but that does require the right level of access)
A stored procedure to upsert masks all that DB logic from the integration, and contains this within the DB where it belongs. Of course, there are many scenarios where you don’t have the right access, or doing this could affect a support policy of a particular application, so in those scenarios you can try to build a SQL query to do this, or as a very last resort, combine individual adapter calls to retrieve/insert/update, creating an upsert service from these, and using this versus the adapters direct.
It’s typically good practice to create a service façade layer in front of the adapters and use these from your integrations versus calling the adapters directly as this can help to shield your integrations from adapter changes/etc which can happen at times, and help to alleviate the ripple effect of such changes.
It also means that for example, should you move away from direct DB integration to REST APIs, the façade can just be changed to invoke the REST APIs and the integration logic would continue to wokr.