Few otherwise general-purpose languages bother to deeply integrate with (relational) databases. Most languages I've seen that do do some integration (though fairly shallowly) are bolt-on abominations. Links is quite a bit more principled, and I believe can actually more or less do what you want. It's a statically typed functional language whose goal was to collapse multi-tier web applications into one coherent (source) program.
In Haskell, a general-purpose, statically typed, purely functional language with no database integration, you can use the type class system and type inference to propagate information about the used fields back to the query site. The simplest approach to this will not actually know what columns are on the table, and so will lead to queries that may access columns that don't exist. Part of the reason I think Links can do what you want is that the type systems of Haskell and Links have some relation, and Phil Wadler, one of the primary designers of Links, is also the creator of type classes. (The mechanism is different though, using row types rather than type classes. Indeed, the approach in Haskell would be more like a poor man's row types.)
That said, it's not clear how desirable this actually is, especially when given a clean, modular syntax for making queries e.g. something like C#'s Linq. Using Linq is like your solution of passing in the list of required fields except you have the full flexibility of, at least, Linq's query syntax and so you aren't just slinging strings about and thus can't typo one of the fields. You're still required to change the query to return the appropriate fields, but often you do want some awareness and control over the query. (This is especially true if the code isn't validated against the schema and so typoing a field name can lead to non-existent column names in the query.)