Object & help system procedures
Status: Reviewed
Stack: PowerShell → SQL / stored procs → Blazor
Depends on: SQL-CLI-09 (overview), SQL-CLI-01 (calling), SQL-CLI-07 (pipeline shapes)
Goal: Know when to use sp_help* / sp_spaceused / sp_helptext / sp_rename vs catalog views/DMVs for inventory and ops scripts feeding Blazor.
Sources: Microsoft Learn (sql-server-ver17 / 2026). Expands SQL-CLI-09 §3.2 (database/objects) only — do not treat this as a rewrite of the overview. Calling: SQL-CLI-01. Staging → Blazor: SQL-CLI-07.
1. Scope map
| In this doc (09b) |
Out → sibling |
sp_help, sp_helpdb, sp_helpfile, sp_helpfilegroup |
Config / sp_configure / who → 09a |
sp_helpindex, ODBC catalog procs (sp_columns, sp_tables, …) |
Security / principals / orphans → 09c |
sp_helptext, encrypted-module caveat |
Agent (msdb help/start/history) → 09d |
sp_spaceused (+ @updateusage / @oneresultset) |
Surface area / xp_* → 09e |
sp_rename (table/column/index OK; never modules) |
Full call patterns / decision table → CLI-09 |
Deprecated deps: sp_depends / sp_MSdependencies → catalog/DMFs |
Pipeline shapes → CLI-07 |
Write path that stays a proc: sp_rename (and only for the object classes called out below).
Read path for Blazor: always catalog views / DMVs — never scrape multi-result-set sp_help* into a grid.
2. Decision: interactive help procs vs catalog for Blazor staging
| Need |
Prefer |
Why |
| One-off peek in SSMS / sqlcmd |
sp_help / sp_helpindex / sp_spaceused |
Zero join typing; human-readable |
| Inventory → staging table → Blazor |
Catalog / DMVs |
One result set, typed columns, WHERE/JOIN, stable shape |
| Module definition into a string column |
sys.sql_modules / OBJECT_DEFINITION() |
Single nvarchar(max) — not 255-char chunks |
| Fleet space / row counts |
sys.dm_db_partition_stats (+ files via sys.master_files) |
Filterable; no @updateusage side effects |
| Rename table / column / index / constraint |
sp_rename |
Official API — then fix dependents yourself |
| Rename proc / view / fn / trigger |
DROP + CREATE (or SSDT publish) |
See §3.8 — definition text does not follow rename |
| Dependency graph for refactor |
sys.sql_expression_dependencies + sys.dm_sql_*_entities |
sp_depends deprecated; incomplete |
Multi-result-set problem (why Blazor hates sp_help*)
| Caller |
Behavior with multi-set procs |
| sqlcmd / go-sqlcmd |
Prints all sets to stdout — fine for eyeballs; ugly for -o CSV / parsers |
Invoke-Sqlcmd |
Typically surfaces the last result set as objects — earlier sets silently dropped |
ADO.NET / SqlCommand |
Can walk NextResult() — doable, not worth it for inventory |
Rule for this stack: Collect with a single-select catalog query into dbo.*Staging (CLI-07). Use help procs only for interactive triage or rare control-plane renames.
3. Deep catalog — high-value object / help procs
Columns per proc: purpose · args · result-set quirks · permissions · prefer-instead.
3.1 sp_help
|
|
| Purpose |
Object metadata dump: name/owner/type; for tables also columns, identity, RowGuid, filegroup, indexes, constraints, references, etc. |
| Args |
@objname = N'schema.object' or omit (list all objects in current DB) |
| Result quirks |
Many result sets — shape depends on object type. Current DB only. Exposes only orderable index columns (no XML/spatial detail). |
| Perms |
public + object visibility; constraint/detail often needs VIEW DEFINITION / ownership |
| Prefer instead |
sys.objects + sys.columns + sys.indexes + sys.index_columns + sys.key_constraints / sys.foreign_keys / sys.check_constraints + sys.types |
-- Interactive only
EXEC sp_help N'dbo.MyTable';
3.2 sp_helpdb
|
|
| Purpose |
DB size / owner / created / status string / compat; with @dbname, second set = file layout |
| Args |
@dbname or omit (all DBs) |
| Result quirks |
1 set (all) or 2 sets (named DB). status is a comma soup — incomplete vs sys.databases. db_size is a display string. Applies to: SQL Server (on-prem / MI-class file layout); thin/absent on Azure SQL DB. |
| Perms |
public in target DB (named) or master (all) |
| Prefer instead |
sys.databases + sys.master_files (size = size * 8.0 / 1024 MB) |
3.3 sp_helpfile / sp_helpfilegroup
| Proc |
Purpose |
Args |
Quirks |
Prefer instead |
sp_helpfile |
Logical/physical file attrs for current DB |
@filename or all |
Size/growth as strings; log → filegroup NULL. SQL Server–centric. |
sys.database_files (current) / sys.master_files (instance) |
sp_helpfilegroup |
Filegroup list + optional file members |
@filegroupname or all |
Multi-set when named; includes FILESTREAM/memory-optimized notes in modern builds |
sys.filegroups + sys.database_files |
Ops tip: For attach/detach planning, sp_helpfile is a fast interactive peek. For Blazor disk inventory, query sys.master_files once per instance.
3.4 sp_helpindex — and sp_helptable?
sp_helpindex
|
|
| Purpose |
Index name / description (incl. filegroup, uniqueness, clustered) / key list for a table or view |
| Args |
@objname (required) |
| Result quirks |
One set. Descending keys marked with -. Does not expose XML/spatial indexes. Description is a free-text blob — hard to parse. |
| Perms |
public |
| Prefer instead |
sys.indexes + sys.index_columns + sys.columns (+ sys.partitions for row counts per index) |
sp_helptable
Not relevant on modern SQL Server. There is no documented sp_helptable in Learn sql-server-ver17. Sybase heritage / folklore — use sp_help interactively or catalog views for scripts. Do not put it in runbooks.
3.5 ODBC-style catalog procs (brief)
These implement ODBC dictionary functions. Still present; not first-choice for Blazor staging (ODBC column names, wildcards, limited richness).
| Proc |
ODBC cousin |
Typical args |
Prefer instead |
sp_tables |
SQLTables |
@table_name, @table_owner, @table_type, @fUsePattern |
sys.tables / sys.views / sys.objects |
sp_columns |
SQLColumns |
@table_name, @table_owner, @column_name, @ODBCVer |
sys.columns + sys.types |
sp_pkeys |
SQLPrimaryKeys |
@table_name, @table_owner |
sys.key_constraints + sys.index_columns where is_primary_key = 1 |
sp_stored_procedures |
SQLProcedures |
@sp_name, @sp_owner, @fUsePattern |
sys.procedures / sys.objects (type IN ('P','PC')) |
sp_fkeys, sp_statistics, … |
FK / index stats |
(see Learn Catalog stored procedures) |
sys.foreign_keys / sys.indexes |
Worth knowing when debugging ODBC/JDBC metadata; skip for inventory scripts.
3.6 sp_helptext
|
|
| Purpose |
Print definition of unencrypted module / rule / default / computed column / CHECK as text rows |
| Args |
@objname (required); optional @columnname for computed column on a table |
| Result quirks |
One column Text nvarchar(255) — definition chunked across rows. Must concatenate in order. Synapse: not supported → use OBJECT_DEFINITION / sys.sql_modules. |
| Perms |
public for system objects; user objects need owner or ALTER / CONTROL / TAKE OWNERSHIP / VIEW DEFINITION |
| Prefer instead |
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID(N'schema.obj'); or OBJECT_DEFINITION(OBJECT_ID(…)) |
Encrypted modules caveat
| Situation |
What you get |
WITH ENCRYPTION proc/view/fn/trigger |
sp_helptext → message that it is encrypted; sys.sql_modules.definition = NULL; OBJECT_DEFINITION = NULL |
| CLR modules |
No T-SQL text in sql_modules the same way — assembly lives elsewhere |
| System procs |
Definitions often visible via sp_helptext / modules (implementation detail; don’t rely on editing them) |
Ops rule: Inventory “do we have the source?” with definition IS NULL on sys.sql_modules joined to sys.objects — not by scraping sp_helptext errors.
3.7 sp_spaceused
|
|
| Purpose |
Rows + reserved/data/index/unused for a table/indexed view/queue, or whole-DB space summary |
| Args |
@objname; @updateusage (true/false); @mode (Stretch — deprecated feature); @oneresultset (bit); @include_total_xtp_storage (In-Mem, when single set) |
| Result quirks |
DB mode default = two result sets. @oneresultset = 1 → one set (PS-friendly). Space columns are varchar with units (KB), not pure numbers. Object mode: schema name not returned. Deferred drop after big truncate/index drop → numbers lag. |
| Perms |
Execute: public. @updateusage = true: db_owner (runs DBCC UPDATEUSAGE) |
| Prefer instead |
sys.dm_db_partition_stats + sys.allocation_units / sys.partitions; files via sys.master_files |
@updateusage caveat
- Forces
DBCC UPDATEUSAGE — can be expensive on large DBs; takes locks/IO.
- Use only when you suspect wrong space after schema churn (dropped indexes, etc.), not on every inventory tick.
- Prefer scheduled
DBCC UPDATEUSAGE in a maintenance window over sprinkling @updateusage='true' in Blazor collectors.
-- Acceptable one-shot from PowerShell (single set)
EXEC sp_spaceused @oneresultset = 1;
-- Prefer for fleets (numeric, joinable) — see §4
3.8 sp_rename
|
|
| Purpose |
Rename user object in current DB: table, column, index, constraint, statistics, alias/CLR type, database (@objtype = 'DATABASE') |
| Args |
@objname, @newname, optional @objtype (COLUMN | INDEX | OBJECT | STATISTICS | USERDATATYPE | DATABASE) |
| Result quirks |
Returns informational messages (e.g. caution about breaking scripts). New name is one-part only. Synapse/Fabric: narrower @objtype support (often COLUMN / OBJECT only — check platform). |
| Perms |
ALTER on object; type → CONTROL; database rename → sysadmin / dbcreator; ledger table → ALTER LEDGER |
OK vs NEVER
| Target |
OK? |
Why |
| Table, column, index, constraint, stats, type |
Yes (with dependency work) |
Metadata name updates; PK/UQ rename can cascade to related index/constraint |
| Stored proc, view, function, trigger |
NEVER for production renames |
sys.sql_modules.definition / OBJECT_DEFINITION still contain the old name — object name and body diverge. Scripts, sp_helptext, and redeploys lie. DROP + CREATE (or dacpac) instead. |
| Any object with dependents |
Only after inventory |
Refs do not auto-update. Check sys.sql_expression_dependencies first; fix views/procs/jobs manually. SELECT * views may need sp_refreshsqlmodule / sp_refreshview after column rename. |
-- Table
EXEC sys.sp_rename N'dbo.OldTable', N'NewTable'; -- @objtype optional for objects
-- Column
EXEC sys.sp_rename N'dbo.T.OldCol', N'NewCol', N'COLUMN';
-- Index
EXEC sys.sp_rename N'dbo.T.IX_Old', N'IX_New', N'INDEX';
-- Modules: do NOT sp_rename — drop/create or publish
3.9 Dependencies — deprecated procs → modern catalog
| Old |
Status |
Replacement |
sp_depends |
Deprecated (Learn ver17: will be removed) |
sys.dm_sql_referencing_entities / sys.dm_sql_referenced_entities |
sp_MSdependencies |
Undocumented / unsupported |
Same DMFs + sys.sql_expression_dependencies |
| SSMS “View Dependencies” |
UI only |
Fine interactively; scripts use catalog/DMFs |
-- What references this object?
SELECT referencing_schema_name, referencing_entity_name, referencing_class_desc
FROM sys.dm_sql_referencing_entities(N'dbo.MyTable', N'OBJECT');
-- What does this module reference?
SELECT referenced_schema_name, referenced_entity_name, referenced_class_desc,
is_caller_dependent, is_ambiguous
FROM sys.dm_sql_referenced_entities(N'dbo.usp_MyProc', N'OBJECT');
-- Database-wide soft dependency edges
SELECT OBJECT_SCHEMA_NAME(referencing_id) AS src_schema,
OBJECT_NAME(referencing_id) AS src_object,
referenced_schema_name, referenced_entity_name, referenced_server_name
FROM sys.sql_expression_dependencies;
Limits: No dependency rows for temp tables, rules/defaults (legacy), many dynamic-SQL names, or cross-DB unless recorded. Always treat as necessary but not sufficient before a rename/drop.
3.10 Other object-help procs still worth knowing (thin)
| Proc |
When |
Prefer instead for Blazor |
sp_helptrigger |
Interactive triggers on a table |
sys.triggers + sys.trigger_events |
sp_helpconstraint |
Interactive constraints on a table |
sys.check_constraints / defaults / FKs / keys |
sp_refreshview / sp_refreshsqlmodule |
After column rename / SELECT * drift |
Keep — fix tools, not inventory |
| ODBC set (§3.5) |
Driver debugging |
Catalog views |
4. Inventory patterns — catalog queries that replace sp_help*
Stable shapes for dbo.*Staging → merge → Blazor (CLI-07). Always SET NOCOUNT ON.
4.1 Objects (replaces bare sp_help)
SET NOCOUNT ON;
SELECT
@@SERVERNAME AS instance_name,
DB_NAME() AS database_name,
SCHEMA_NAME(o.schema_id) AS schema_name,
o.name AS object_name,
o.object_id,
o.type AS type_code,
o.type_desc,
o.create_date,
o.modify_date,
o.is_ms_shipped,
SYSUTCDATETIME() AS collected_utc
FROM sys.objects AS o
WHERE o.is_ms_shipped = 0
ORDER BY schema_name, o.type, object_name;
4.2 Columns (replaces sp_help column set / sp_columns)
SET NOCOUNT ON;
SELECT
SCHEMA_NAME(t.schema_id) AS schema_name,
t.name AS table_name,
c.column_id,
c.name AS column_name,
ty.name AS type_name,
c.max_length, c.precision, c.scale,
c.is_nullable, c.is_identity, c.is_computed,
c.is_rowguidcol
FROM sys.tables AS t
JOIN sys.columns AS c ON c.object_id = t.object_id
JOIN sys.types AS ty ON ty.user_type_id = c.user_type_id
ORDER BY schema_name, table_name, c.column_id;
4.3 Indexes (replaces sp_helpindex)
SET NOCOUNT ON;
SELECT
SCHEMA_NAME(t.schema_id) AS schema_name,
t.name AS table_name,
i.name AS index_name,
i.index_id, i.type_desc,
i.is_unique, i.is_primary_key, i.is_unique_constraint,
i.filter_definition,
STRING_AGG(
CASE WHEN ic.is_included_column = 0
THEN c.name + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE '' END
END, ', ') WITHIN GROUP (ORDER BY ic.key_ordinal) AS key_columns
FROM sys.tables AS t
JOIN sys.indexes AS i ON i.object_id = t.object_id AND i.index_id > 0
JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
JOIN sys.columns AS c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
GROUP BY t.schema_id, t.name, i.name, i.index_id, i.type_desc,
i.is_unique, i.is_primary_key, i.is_unique_constraint, i.filter_definition;
4.4 Module definitions (replaces sp_helptext)
SET NOCOUNT ON;
SELECT
SCHEMA_NAME(o.schema_id) AS schema_name,
o.name AS module_name,
o.type_desc,
CASE WHEN m.definition IS NULL THEN 1 ELSE 0 END AS is_encrypted_or_unavailable,
m.definition, -- nvarchar(max); Invoke-Sqlcmd: raise -MaxCharLength
m.uses_ansi_nulls, m.uses_quoted_identifier
FROM sys.sql_modules AS m
JOIN sys.objects AS o ON o.object_id = m.object_id
WHERE o.is_ms_shipped = 0;
4.5 Space / rows (replaces sp_spaceused fleets)
SET NOCOUNT ON;
SELECT
SCHEMA_NAME(o.schema_id) AS schema_name,
o.name AS object_name,
SUM(ps.row_count) AS row_count,
SUM(ps.reserved_page_count) * 8 AS reserved_kb,
SUM(ps.used_page_count) * 8 AS used_kb,
(SUM(ps.reserved_page_count) - SUM(ps.used_page_count)) * 8 AS unused_kb
FROM sys.dm_db_partition_stats AS ps
JOIN sys.objects AS o ON o.object_id = ps.object_id
WHERE o.type IN ('U', 'V') -- tables; indexed views appear as V with indexes
AND ps.index_id IN (0, 1) -- heap or clustered only for row_count
GROUP BY o.schema_id, o.name
ORDER BY reserved_kb DESC;
4.6 Files / DBs (replaces sp_helpdb / sp_helpfile)
SET NOCOUNT ON;
SELECT
d.name AS database_name,
d.database_id, d.state_desc, d.recovery_model_desc,
d.compatibility_level, d.collation_name,
SUSER_SNAME(d.owner_sid) AS owner_name,
mf.name AS logical_name, mf.type_desc,
mf.physical_name,
mf.size * 8.0 / 1024 AS size_mb,
CASE WHEN mf.max_size = -1 THEN NULL ELSE mf.max_size * 8.0 / 1024 END AS max_size_mb,
mf.growth, mf.is_percent_growth
FROM sys.databases AS d
JOIN sys.master_files AS mf ON mf.database_id = d.database_id
ORDER BY database_name, mf.type, mf.file_id;
5. Gotchas
| Gotcha |
Impact |
Mitigation |
Multi-result sets + Invoke-Sqlcmd |
You keep the last set only; Blazor staging silently incomplete |
Don’t stage from sp_help / sp_helpdb (named). Use §4 queries or @oneresultset = 1 for sp_spaceused |
sp_helptext 255-char rows |
Naive ConvertTo-Json on rows ≠ full module |
sys.sql_modules.definition; set -MaxCharLength high enough (CLI-03) |
| Collation |
Join name across DBs / temp / catalog can fail with collation conflict |
COLLATE DATABASE_DEFAULT on join keys; inventary columns as nvarchar |
| Temp tables |
sp_help on #t works in-session; catalog queries need that session; deps DMFs ignore temps |
Don’t inventory temps for Blazor; session-scoped only |
| Deferred space release |
sp_spaceused right after huge truncate/index drop looks “full” |
Wait for background cleanup, or trust DMVs later; avoid panicking capacity alerts |
@updateusage |
Heavy; needs db_owner |
Never on a 5-minute collector; maintenance window only |
sp_rename modules |
Name ≠ definition text |
Ban in CI; allow only table/column/index/constraint |
| Azure SQL DB |
No full instance sys.master_files story like on-prem; sp_helpdb/sp_helpfile thin or N/A; no Agent |
Use sys.database_files, Azure metrics / CLI-05; skip Agent siblings |
| Azure Synapse |
sp_helptext unsupported; sp_rename limited (often column-focused) |
OBJECT_DEFINITION / sys.sql_modules; check platform docs before rename scripts |
Cross-db sp_help* |
Looks in current DB only |
USE / -d per DB loop (CLI-01) |
6. Recipes (sqlcmd + Invoke-Sqlcmd + catalog equivalents)
R1 — Interactive object peek (sqlcmd)
sqlcmd -S "$SQL_SERVER" -E -d "$SQL_DB" -Q "EXEC sp_help N'dbo.MyTable';"
R2 — Indexes interactive (catalog: §4.3)
sqlcmd -S "$SQL_SERVER" -E -d "$SQL_DB" -Q "EXEC sp_helpindex N'dbo.MyTable';"
R3 — sp_spaceused single set (acceptable PS) vs DMV
Invoke-Sqlcmd -ServerInstance $env:SQL_SERVER -Database $env:SQL_DB -TrustServerCertificate `
-Query "EXEC sp_spaceused @oneresultset = 1;"
# Preferred fleet shape
$q = Get-Content -Raw .\space-by-table.sql # §4.5
Invoke-Sqlcmd -ServerInstance $env:SQL_SERVER -Database $env:SQL_DB -TrustServerCertificate -Query $q |
Export-Csv ".\space-$($env:SQL_SERVER)-$($env:SQL_DB).csv" -NoTypeInformation
R4 — Module text: never chunk-scrape
$q = @"
SET NOCOUNT ON;
SELECT OBJECT_SCHEMA_NAME(object_id) AS schema_name, OBJECT_NAME(object_id) AS module_name,
definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID(N'dbo.usp_MyProc');
"@
Invoke-Sqlcmd -ServerInstance $env:SQL_SERVER -Database $env:SQL_DB -TrustServerCertificate `
-MaxCharLength 1000000 -Query $q
R5 — Encrypted / missing definition audit
SET NOCOUNT ON;
SELECT SCHEMA_NAME(o.schema_id) AS schema_name, o.name, o.type_desc
FROM sys.objects AS o
JOIN sys.sql_modules AS m ON m.object_id = o.object_id
WHERE m.definition IS NULL AND o.is_ms_shipped = 0
ORDER BY 1, 2;
R6 — Rename column (with dependency check first)
-- 1) Who references this table?
SELECT referencing_schema_name, referencing_entity_name
FROM sys.dm_sql_referencing_entities(N'dbo.MyTable', N'OBJECT');
-- 2) Rename
EXEC sys.sp_rename N'dbo.MyTable.OldCol', N'NewCol', N'COLUMN';
-- 3) Refresh any SELECT * modules if needed
-- EXEC sys.sp_refreshsqlmodule N'dbo.vw_Something';
R7 — sqlcmd CSV: object inventory (catalog)
sqlcmd -S "$SQL_SERVER" -E -d "$SQL_DB" -b -s"," -W \
-Q "SET NOCOUNT ON;
SELECT SCHEMA_NAME(schema_id) AS schema_name, name, type, type_desc, create_date, modify_date
FROM sys.objects WHERE is_ms_shipped = 0 ORDER BY 1, 2;" \
-o "./objects_${SQL_SERVER}_${SQL_DB}.csv"
R8 — Invoke-Sqlcmd → JSON for Blazor cache / API
$q = @"
SET NOCOUNT ON;
SELECT @@SERVERNAME AS InstanceName, DB_NAME() AS DatabaseName,
SCHEMA_NAME(o.schema_id) AS SchemaName, o.name AS ObjectName,
o.type AS TypeCode, o.type_desc AS TypeDesc,
o.create_date AS CreateDate, o.modify_date AS ModifyDate,
SYSUTCDATETIME() AS CollectedUtc
FROM sys.objects AS o WHERE o.is_ms_shipped = 0;
"@
$rows = Invoke-Sqlcmd -ServerInstance $env:SQL_SERVER -Database $env:SQL_DB `
-TrustServerCertificate -Query $q
$rows | ConvertTo-Json -Depth 3 | Set-Content ".\objects-$($env:SQL_SERVER).json" -Encoding UTF8
R9 — Dependency gate before drop/rename
sqlcmd -S "$SQL_SERVER" -E -d "$SQL_DB" -b -Q "
SET NOCOUNT ON;
SELECT referencing_schema_name, referencing_entity_name, referencing_class_desc
FROM sys.dm_sql_referencing_entities(N'dbo.MyTable', N'OBJECT');
"
R10 — DB file layout catalog (replaces sp_helpdb/sp_helpfile for staging)
sqlcmd -S "$SQL_SERVER" -E -d master -b -s"," -W -i ./files-inventory.sql -o "./files_${SQL_SERVER}.csv"
# files-inventory.sql body = §4.6
7. Pointers to 09a / 09c / 09d / 09e
| Doc |
Covers |
| SQL-CLI-09 |
Overview: call patterns, procs vs DMVs, curated catalog |
| SQL-CLI-09a |
sp_configure / RECONFIGURE / sys.configurations; sp_who* honesty |
| 09b (this) |
Object help, space, text, rename, dependency replacements |
| 09c |
Security / logins / users / roles; deprecated sp_change_users_login; modern DDL |
| 09d |
Agent: sp_help_job / sp_start_job / history vs msdb tables |
| 09e |
Surface area / xp_cmdshell / Ole Automation — policy & safer alternatives |
Related stack: SQL-CLI-01 (calling / -b / -d), SQL-CLI-07 (Collect→Stage→Blazor), SQL-CLI-03 (-MaxCharLength).
Learn anchors (ver17): sp_help, sp_helpdb, sp_helpfile, sp_helpfilegroup, sp_helpindex, sp_helptext, sp_spaceused, sp_rename, sp_depends (deprecated), Catalog stored procedures, sys.sql_modules, sys.sql_expression_dependencies, sys.dm_sql_referencing_entities, sys.dm_sql_referenced_entities, sys.dm_db_partition_stats.