Skip to content

Commit ee0bb63

Browse files
BrentOzarclaude
andcommitted
README: document sp_ineachdb and its Azure SQL DB behavior
Adds a new top-level section covering sp_ineachdb's parameters, the Azure SQL DB code path (EngineEdition 5), and the caveats that come with the @command rewriter (string-literal false positives, non-canonical whitespace, Managed Instance exemption). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8dbac3f commit ee0bb63

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,47 @@ For information about how this works, see [Tara Kizer's white paper on Log Shipp
535535

536536

537537

538+
## sp_ineachdb: Run a Command in Each Database
539+
540+
`sp_ineachdb` is a drop-in replacement for the undocumented `sp_MSforeachdb` with saner filtering and error handling. Pass a command string using `?` as a placeholder for the database name:
541+
542+
```tsql
543+
EXEC sp_ineachdb @command = N'SELECT DB_NAME() AS db, COUNT(*) AS tables FROM [?].sys.tables;';
544+
```
545+
546+
Useful parameters:
547+
548+
* `@command` - the T-SQL to run. `?` (or whatever you set `@replace_character` to) gets replaced with the quoted database name.
549+
* `@database_list`, `@exclude_list` - comma-separated lists of databases to include or exclude. Bracket-quote names that contain special characters.
550+
* `@name_pattern`, `@exclude_pattern` - LIKE patterns applied to database names.
551+
* `@system_only`, `@user_only` - limit to system DBs (master/model/msdb/tempdb/distribution) or user DBs.
552+
* `@recovery_model_desc`, `@compatibility_level`, `@is_read_only`, `@is_auto_close_on`, `@is_auto_shrink_on`, `@is_broker_enabled`, `@is_query_store_on`, `@user_access`, `@state_desc` - filter by database property.
553+
* `@is_ag_writeable_copy = 1` - skip Availability Group secondaries.
554+
* `@print_dbname`, `@print_command`, `@print_command_only`, `@select_dbname` - diagnostics for debugging your command string without running it.
555+
556+
### Azure SQL DB support
557+
558+
Azure SQL DB forbids cross-database calls and 3-part object names, so "run in each database" collapses to "run in the current database" (Azure SQL DB sessions are bound to one user database anyway). `sp_ineachdb` detects Azure SQL DB via `SERVERPROPERTY('EngineEdition') = 5` and adapts automatically:
559+
560+
* Seeds the database list with just the current database.
561+
* Executes `@command` via `EXEC sys.sp_executesql` instead of a 3-part dynamic call.
562+
* Rewrites common `sp_MSforeachdb`-style patterns in `@command` so they don't have to be changed:
563+
* `USE [?];` and `USE ?;` (with or without brackets or semicolons) are stripped - you can't change database context in Azure SQL DB.
564+
* `[?].schema.object` and `?.schema.object` are collapsed to `schema.object`, turning 3-part names into 2-part names.
565+
566+
This means callers that already work with `sp_MSforeachdb` on box SQL (like `sp_Blitz` internals) can call `sp_ineachdb` on Azure SQL DB and Just Work.
567+
568+
**Things to look out for on Azure SQL DB:**
569+
570+
* **Placeholders inside string literals get rewritten too.** `PRINT 'See [?].sys.tables'` will have `[?].` stripped out - avoid putting the placeholder inside quoted strings. (This caveat also applies to box SQL, since `@command` text substitution happens everywhere.)
571+
* **Non-canonical whitespace isn't matched.** `USE [?];` (double space) or `[?] . sys . tables` (spaces between name parts) won't be rewritten. Stick to the canonical `USE [?];` and `[?].sys.tables` forms.
572+
* **Managed Instance is not affected.** Azure SQL Managed Instance reports `EngineEdition = 8` and supports cross-database calls, so it uses the same code path as box SQL.
573+
* **Filter parameters still apply** - the current database is added to the list, then the usual `@name_pattern`, `@user_only`, property filters, etc. can still exclude it. If nothing matches, you get the normal `No databases to process.` message.
574+
575+
[*Back to top*](#header1)
576+
577+
578+
538579
## Parameters Common to Many of the Stored Procedures
539580

540581
* @Help = 1 - returns a result set or prints messages explaining the stored procedure's input and output. Make sure to check the Messages tab in SSMS to read it.

0 commit comments

Comments
 (0)