Stored Procedures (Blazor API Surface)

Status: Reviewed (deep-dive v1)
Stack note: PowerShell collectors and Blazor Server should talk to SQL through usp_* procs — not ad-hoc SQL, not scalar UDFs as the API.
Pairs with: SQL-11 (UDFs stay inside T-SQL), SQL-13 (#temp staging in procs), SPIKE-01…08 board shapes.
Goal: Authoring, calling, security, and hygiene patterns for the maintenance warehouse API.


Quick chooser

Need Do this
Blazor page needs data or an action One proc per use-case (usp_Alert_GetOpenBoard, usp_Alert_Ack)
Reuse a query shape in many procs View or inline TVF — not a second “API” UDF
Multi-step staging Proc + #temp (SQL-13)
Filter list from UI TVP or typed params — not concatenated SQL
Job / Agent automation Same procs Blazor uses, or thin wrappers

Naming & layout

usp_<Area>_<Verb><Object>
  usp_Inventory_GetInstances
  usp_Backup_GetHeatmap
  usp_Alert_Evaluate          -- Agent-facing
  usp_Alert_Ack               -- UI-facing write

Skeleton (every proc)

CREATE OR ALTER PROC dbo.usp_Example_GetBoard
  @SqlInstanceId int = NULL,
  @UnackedOnly bit = 0
AS
BEGIN
  SET NOCOUNT ON;
  SET XACT_ABORT ON;  -- optional but good for write procs

  -- reads: no outer tran needed
  SELECT …
  FROM …
  WHERE (@SqlInstanceId IS NULL OR i.SqlInstanceId = @SqlInstanceId)
    AND (@UnackedOnly = 0 OR a.Status = 'Open');
END;

Checklist on create:


Read vs write procs

Kind Examples Notes
Read board GetOpenBoard, GetHeatmap, GetOutOfDate Filter params; ORDER BY for UI; no side effects
Read detail GetDetail @Id Single entity + child rows (events)
Command Ack, Evaluate Validate state; write + optional event row; no kill/revoke/patch from UI
Merge/load Collector merge from PS Idempotent upsert; run under Agent/PS credential

Hard rule (SPIKE): UI procs never start Agent jobs, revoke logins, or run backups — boards are observe + ack only.


Calling from Blazor / ADO

// shape only — CommandType.StoredProcedure, parameters for @UnackedOnly etc.

Calling from PowerShell

Invoke-Sqlcmd -ServerInstance $Wh -Database $Db `
  -Query 'EXEC dbo.usp_Alert_Evaluate'  # or AddWithValue params for filters

Collectors: bulk load staging → usp_*_Merge. Don’t embed giant scripts in PS when a proc owns the logic.


Parameters & TVPs


Security


Performance habits


Common failure patterns

Symptom Likely cause
Blazor timeout on board Fat join / missing index / Evaluate called from UI thread
Extra empty result sets Missing SET NOCOUNT ON or debug SELECT left in
Wrong user on Ack @AckedBy not from auth; client spoof
Works in SSMS, fails in app Different login rights; default DB; ansi settings
“API” is a scalar UDF Wrong layer — wrap as proc

Estate map (SPIKE → proc)

Area Example procs
Inventory usp_Inventory_GetInstances, merge from PS
Backup usp_Backup_GetHeatmap
Agent usp_Agent_GetFailBoard
Alerts usp_Alert_Evaluate, usp_Alert_GetOpenBoard, usp_Alert_Ack
Capacity / perf / security / build Same Get* board pattern

Done when


SQL Dude — SQL-12 Stored Procedures v1