SQL SERVER | Ricercare un testo in tutte le stored procedure
Come cercare una stringa nel codice di tutte le stored procedure di un database SQL Server, con la query moderna su sys.sql_modules, l'estensione a viste, funzioni e trigger e il motivo per cui la vecchia query su syscomments perde dei risultati.
Capita spesso di dover sapere dove viene usata una certa cosa dentro un database: il nome di una tabella che stai per rinominare, una colonna che vuoi eliminare, un valore hardcoded, il nome di un linked server che sta cambiando. Cliccare una per una le stored procedure in Management Studio non è praticabile quando ce ne sono centinaia.
La query giusta interroga direttamente i metadati del database e restituisce l’elenco degli oggetti il cui codice contiene il testo cercato.
La query
SELECT
o.name AS Oggetto,
o.type_desc AS Tipo,
o.modify_date AS UltimaModifica
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o ON o.object_id = m.object_id
WHERE m.definition LIKE '%testo da ricercare%'
ORDER BY o.type_desc, o.name;
Sostituisci testo da ricercare con la stringa che ti interessa, mantenendo i due % attorno.
Così com’è, la query cerca in tutti gli oggetti programmabili: stored procedure, viste, funzioni, trigger. Nella pratica è quasi sempre ciò che serve, perché un riferimento a una tabella può nascondersi in una vista tanto quanto in una procedura. Se invece vuoi limitarti alle sole stored procedure, aggiungi il filtro sul tipo:
AND o.type = 'P'
I valori utili di o.type sono P per le stored procedure, V per le viste, FN / IF / TF per le funzioni scalari e tabellari, TR per i trigger.
Perché non usare syscomments
La query che si trova più spesso in giro, ed è quella che circolava anche qui, si appoggia a SysObjects e SysComments:
-- Sconsigliata: può perdere dei risultati
SELECT o.name
FROM SysObjects AS o
INNER JOIN SysComments AS c ON o.id = c.id
WHERE c.[text] LIKE '%testo da ricercare%'
AND o.[type] = 'P'
Funziona ancora per retrocompatibilità, ma ha un difetto concreto: syscomments spezza il codice degli oggetti in blocchi da 4000 caratteri, distribuiti su più righe. Se la stringa che cerchi cade a cavallo tra due blocchi, il LIKE non la trova e la procedura non compare nei risultati — senza alcun errore. Su procedure lunghe questo produce falsi negativi silenziosi, che è il peggior modo di sbagliare quando stai verificando l’impatto di una modifica.
sys.sql_modules invece espone la definizione completa in un unico campo nvarchar(max), quindi la ricerca è affidabile. In più syscomments è dichiarata deprecata da Microsoft: è tra le viste di compatibilità mantenute solo per non rompere il codice vecchio.
Attenzione agli oggetti cifrati
Un dettaglio che fa perdere tempo: se una stored procedure è stata creata WITH ENCRYPTION, la sua definizione non è leggibile e m.definition vale NULL. Quell’oggetto non comparirà mai nei risultati, qualunque cosa contenga. Per sapere se nel database ci sono oggetti in questa condizione:
SELECT o.name, o.type_desc
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o ON o.object_id = m.object_id
WHERE m.definition IS NULL;
Se la lista non è vuota, tienine conto: sono punti ciechi della tua ricerca.
Leggi anche: