My best practice doesn't fit either of your suggestions... If I am creating a new database layer (which I have numerous times) then the caller would never provide the SQL. If the business layer(s) need new database logic then the database layer should be modified to provide it. The caller provides the parameters that would be used in the call. Then within that database layer method it would decide how to process the parameters and SQL (provided by the method.) So it looks like the following.
void DatabaseDoX(param1, param2,...)
{
// multiple variations possible
std::string fullyFormedQuery = sprintf (SQL_X, param1, param2, ... );
There are quite a few variations on the above. For example consider the complication of a user initiated call where they might specify different 'query' terms (like data range, customer name, etc) But all still hide the SQL. Certainly there are design considerations for example your code might be coming from within the database layer (not a business call at all.) If so then I suspect that usage would actually vary depending on what the database layer was specifically doing in the code path.