Come posso rilevare le procedure memorizzate interrotte dopo una modifica dello schema?


11

Ho modificato una tabella centrale nel mio database e sp_depends restituisce letteralmente centinaia di risultati e sono preoccupato che alcune di quelle stored procedure potrebbero non essere più compilate dopo la mia modifica.

Controllare una singola procedura memorizzata è semplice (ho appena rieseguito lo script alter e ho verificato se l'operazione ha esito positivo), ma farlo su oltre 100 procedure è un po 'complicato.

So di poter usare uno script come questo per ricompilare tutti gli oggetti del mio database, ma l'operazione effettiva avrà luogo la prossima volta che la procedura memorizzata verrà eseguita, non immediatamente, quindi non sembra appropriato nel mio caso.

Stavo anche pensando che avrei potuto eliminare del tutto tutte le procedure memorizzate e risincronizzare il mio database con il mio sistema di controllo del codice sorgente, ma quell'opzione, sebbene praticabile, non è molto elegante. C'è un modo migliore per farlo?

Sto usando SQL Server 2008 R2 e gli script del mio database sono archiviati in un progetto di database VS 2008.


Per chiarire, non sto sostenendo che si dovrebbe fare affidamento esclusivamente su questo approccio per testare il codice. Proprio come in c # si rileva istantaneamente un errore di sintassi in altri file dipendenti mentre si codifica (e quindi si utilizzano altre strategie per testare, come i test unitari, che di solito sono diversi ordini di grandezza più lenti), penso che avrebbe senso rilevare le dipendenze SQL errori in pochi secondi anziché dover eseguire un test funzionale completo che in genere può richiedere alcune ore per il completamento.

Risposte:


7

Che ne dici di eseguire i test della tua unità, funzionali, di integrazione e delle prestazioni? Se non si dispone di alcun test, è davvero il momento di iniziare a considerare lo schema del database come codice e trattarlo come tale, inclusi il controllo e il test della versione. Alex Kuznetsov ha un intero libro dedicato a questo argomento: Programmazione difensiva di database con SQL Server .


I test non coprono sempre il 100% del codice e in genere richiedono alcune ore per essere eseguiti. In c #, posso rilevare se il mio codice viene ancora compilato in pochi secondi (indipendentemente dalla sua correttezza). Questo non significa che dovrei spingere il codice (indipendentemente dal fatto che il codice sia c # o PLSQL) in produzione senza testarlo correttamente, ma non sembra irragionevole avere un modo per rilevare rapidamente le dipendenze rotte, vero?
Brann,

2
Sfortunatamente lo stato dell'arte di SQL Server in questo momento rispetto al rilevamento delle dipendenze nella procedura memorizzata è "profondamente interrotto", vedere Informazioni sulle dipendenze SQL o Mantenere i sistemi di aggiornamento aggiornati in SQL Server 2008 . Esistono anche strumenti di terze parti che tentano di risolvere il problema
Remus Rusanu il

2
Ciò rende i test unitari / funzionali praticamente l'unico modo affidabile per rilevare le modifiche di rottura.
Remus Rusanu,

1
Per un rapido controllo, i progetti di database di Visual Studio fanno un lavoro abbastanza decente nella convalida di qualsiasi modifica.
Remus Rusanu,

4

È una soluzione, ma è possibile generare gli script CREATE PROCEDURE per il database (fare clic con il pulsante destro del mouse sul database -> attività -> generare script), trovare e sostituire CREATE PROCEDURE con ALTER PROCEDURE e quindi analizzare.

Spero che tu abbia una risposta migliore qui - anche io sono interessato! :)


Non segnerò la tua risposta come accettata perché spero ancora in una soluzione più pulita (si spera una tracciabile), ma ottieni sicuramente il mio +1! Grazie.
Brann,

3
Questo approccio non ti farà sapere se stai facendo riferimento a una tabella inesistente .
Nick Chammas,

Questo approccio inoltre non funzionerà se lo script generato è più grande di circa 30k righe. Odio il fatto che lo sappia ..
Eonasdan,

3

È possibile utilizzare Sql Server Data Tools (SSDT). Microsoft Visual Studio ti consente di creare un progetto SQL Server. Uno quindi importa il database nel progetto e quindi crea il progetto. Se sono presenti procedure o oggetti archiviati non funzionanti, verrà visualizzato un errore di compilazione.


Aggiungerò che puoi facilmente generare un nuovo database creare script dal progetto SSDT ed eseguirlo in un ambiente di test, che sarà una verifica abbastanza approfondita che non ci siano proc / trigger / etc rotti a causa di modifiche dello schema.
AaronLS,

3

Potresti voler esaminare questa domanda SO che sto cercando un modo affidabile per verificare le procedure memorizzate T-SQL. Qualcuno ne ha preso uno? che sta essenzialmente chiedendo la stessa cosa, con diverse risposte.

Per basarsi sullo script Alaa Awad pubblicato ... questo dovrebbe mostrare lo schema e il database degli oggetti referenziati e referenziati. Se si utilizzano molte tabelle temporanee tramite alias (che a volte vengono visualizzati durante l'utilizzo sys.sql_expression_dependencies), parametri UDTT o altre caratteristiche dinamiche, potrebbe essere necessario utilizzare le funzioni sys.dm_sql_referenced_entitieso sys.dm_sql_referencing_entitiesinvece / anche.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]

1
Dovrebbe aggiungerli alla clausola where: / * Non un tipo utente esistente / AND sed.referenced_entity_name NON IN (SELEZIONA [nome] DA sys.types) / Non un alias * / AND sed.referenced_schema_name NON È NULL
JasonBluefire

1

utilizzare le sys.sql_expression_dependencies aggiunte in SQL Server 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO

Questo può essere utile, tuttavia non è così semplice come anche lo schema deve essere preso in considerazione. Ricevo anche problemi in cui sys.sql_expession_dependencies visualizza l'alias utilizzato anziché la tabella dipendente effettiva, che ovviamente non supera il test object_id (). Infine, visualizza le tabelle definite dall'utente passate come parametri alle stored procedure, il che non è molto utile.
Tabloo Quijico,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.