Skip to content

sp_Blitz: include affected foreign key count in “Foreign Keys Not Trusted” details#3912

Merged
BrentOzar merged 2 commits into
devfrom
copilot/add-foreign-keys-count-to-warning
Apr 15, 2026
Merged

sp_Blitz: include affected foreign key count in “Foreign Keys Not Trusted” details#3912
BrentOzar merged 2 commits into
devfrom
copilot/add-foreign-keys-count-to-warning

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

The sp_Blitz “Foreign Keys Not Trusted” finding (CheckID 48) currently reports only that a database has untrusted foreign keys. This update makes the details message include the number of affected foreign keys in that database.

  • What changed

    • Updated the CheckID 48 query in sp_Blitz.sql to compute and inject the FK count into Details.
    • Replaced the non-counted wording:
      • The [X] database has foreign keys that were...
      • with:
      • The [X] database has Y foreign keys that were...
  • Query shape adjustment for counted output

    • Switched from SELECT DISTINCT 48 to an aggregate SELECT 48 with COUNT(*).
    • Added HAVING COUNT(*) > 0 so rows are emitted only when untrusted FKs exist.
  • Scope

    • Only sp_Blitz.sql was modified.
    • Install%.sql scripts were intentionally not edited.
(''The ['' + DB_NAME() + ''] database has '' + CAST(COUNT(*) AS NVARCHAR(20)) 
 + '' foreign keys that were probably disabled, data was changed, and then the key was enabled again...'')

Copilot AI changed the title [WIP] Update sp_Blitz to include count of affected foreign keys sp_Blitz: include affected foreign key count in “Foreign Keys Not Trusted” details Apr 15, 2026
Copilot AI requested a review from BrentOzar April 15, 2026 14:56
Copy link
Copy Markdown
Member

@BrentOzar BrentOzar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this query now need a group by since it's got a HAVING and a SUM?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 15, 2026

Doesn't this query now need a group by since it's got a HAVING and a SUM?

Good catch to ask. In this case, no GROUP BY is required in SQL Server because the query is a single aggregate group (COUNT(*)) with no grouped columns, and HAVING COUNT(*) > 0 is valid on that implicit group. Also, it’s COUNT(*) (not SUM) in commit 9fad54c.

Copilot AI requested a review from BrentOzar April 15, 2026 15:13
Copy link
Copy Markdown
Member

@BrentOzar BrentOzar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks, Captain Circuits.

@BrentOzar BrentOzar marked this pull request as ready for review April 15, 2026 16:11
Copilot AI review requested due to automatic review settings April 15, 2026 16:12
@BrentOzar BrentOzar merged commit b4e3cef into dev Apr 15, 2026
1 check passed
@BrentOzar BrentOzar deleted the copilot/add-foreign-keys-count-to-warning branch April 15, 2026 16:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates sp_Blitz CheckID 48 (“Foreign Keys Not Trusted”) to include the number of untrusted foreign keys in the Details message for each affected database.

Changes:

  • Switched CheckID 48 output to an aggregate query so it can compute COUNT(*) of untrusted foreign keys.
  • Injected the computed FK count into the Details string.
  • Added HAVING COUNT(*) > 0 to avoid emitting a row when no untrusted foreign keys exist.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sp_Blitz.sql
''Foreign Keys Not Trusted'',
''https://www.brentozar.com/go/trust'',
(''The ['' + DB_NAME() + ''] database has foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'')
(''The ['' + DB_NAME() + ''] database has '' + CAST(COUNT(*) AS NVARCHAR(20)) + '' foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'')
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updated Details string will produce grammatically incorrect output when exactly 1 foreign key is affected ("1 foreign keys"). Consider adding singular/plural handling so the message reads correctly for both 1 and >1.

Suggested change
(''The ['' + DB_NAME() + ''] database has '' + CAST(COUNT(*) AS NVARCHAR(20)) + '' foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'')
(''The ['' + DB_NAME() + ''] database has '' + CAST(COUNT(*) AS NVARCHAR(20)) + CASE WHEN COUNT(*) = 1 THEN '' foreign key that was probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'' ELSE '' foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'' END)

Copilot uses AI. Check for mistakes.
Comment thread sp_Blitz.sql
''https://www.brentozar.com/go/trust'',
(''The ['' + DB_NAME() + ''] database has foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'')
(''The ['' + DB_NAME() + ''] database has '' + CAST(COUNT(*) AS NVARCHAR(20)) + '' foreign keys that were probably disabled, data was changed, and then the key was enabled again. Simply enabling the key is not enough for the optimizer to use this key - we have to alter the table using the WITH CHECK CHECK CONSTRAINT parameter.'')
from [?].sys.foreign_keys i INNER JOIN [?].sys.objects o ON i.parent_object_id = o.object_id INNER JOIN [?].sys.schemas s ON o.schema_id = s.schema_id
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this check aggregates to a single row, the joins to sys.objects and sys.schemas are no longer used for filtering or output. Consider removing the joins and counting directly from sys.foreign_keys to reduce query work and keep the check simpler.

Suggested change
from [?].sys.foreign_keys i INNER JOIN [?].sys.objects o ON i.parent_object_id = o.object_id INNER JOIN [?].sys.schemas s ON o.schema_id = s.schema_id
from [?].sys.foreign_keys i

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sp_Blitz: for "Foreign Keys Not Trusted", add details for the number of foreign keys affected

3 participants