sp_msforeachdb
is kind of... special. And I mean partly in the "riding the short bus" sense of the word (and even that's not entirely fair here; my main complaint is that it's undocumented), but mostly I just mean that it's unique. This syntax is only used with sp_msforeachdb
and sp_msforeachtable
, and nowhere else in Sql Server itself.
What you should think of, though, is if you've ever written code that used an OLE or ODBC provider to do parameterized queries. Those tools use the ?
character as a parameter placeholder. Something similar is going on here. The ?
character is a parameter placeholder, where the value of the parameter will later be set to the name of each DB in your server, including master
, tempdb
, model
, and msdb
.
Try running this code to get a sense of how it works:
EXEC sp_MSforeachdb 'print ''?'' '
It's tempting to use this procedure for things like maintenance, reporting, and alerting scripts, but it's something you probably want to do only sparingly. Best not to rely on undocumented behavior. The sqlblog link posted first in another answer is the standard thinking on the subject.
Basically, there are likely no specific plans to retire or break this procedure (or other sp_*
procedures), but there is also pretty much zero investment in moving these procedures forward from version to version. For example, the linked article indicates that sp_msforeachdb relies on the old dbo.sysdatabases
rather than the more-correct sys.databases
. I wouldn't expect Microsoft to target sp_msforeachdb directly, but if they ever decide to remove dbo.sysdatabases
my expectation would be that their testing will discover that sp_msforeachdb is broken, at which time they'll also just remove sp_msforeachdb rather than fix it.