Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Ricompilare i processi archiviati?

Capisco la tua domanda come "quando apporto una modifica allo schema, voglio convalidare tutte le procedure che vengono ancora eseguite correttamente con il nuovo schema". Cioè. se si elimina una colonna a cui si fa riferimento in un SELECT in una procedura, si desidera che venga contrassegnata poiché richiede modifiche. Quindi, in particolare, non capisco la tua domanda come "Voglio che la procedura venga ricompilata alla prossima esecuzione", poiché quel lavoro è gestito per te dal motore, che rileverà la modifica della versione dei metadati associata a qualsiasi alterazione dello schema e scarterà l'esistente piani di esecuzione memorizzati nella cache.

La mia prima osservazione è che ciò che descrivi nella tua domanda è solitamente compito di un TEST e dovresti avere un passaggio QA nel tuo processo di distribuzione che convalida la nuova "build". La soluzione migliore che potresti avere è implementare un set minimo di unit test che, per lo meno, esegua l'iterazione attraverso tutte le tue procedure memorizzate e convalidi l'esecuzione di ciascuno per correttezza, in una distribuzione di prova. Ciò eliminerebbe praticamente tutte le sorprese, almeno le eliminerebbe dove fa male (in produzione o presso il sito del cliente).

La tua prossima opzione migliore è fare affidamento sui tuoi strumenti di sviluppo per tenere traccia di queste dipendenze. Il Visual Studio Database 2008 Database Edition fornisce tale funzionalità pronta all'uso e si occuperà di convalidare qualsiasi modifica apportata allo schema.

E infine la tua ultima opzione è fare qualcosa di simile a quanto suggerito da KM:automatizzare un'iterazione attraverso tutte le tue procedure a seconda dell'oggetto modificato (e tutte le procedure a seconda di quelle dipendenti e così via in modo ricorsivo). Non basterà segnare le procedure per la ricompilazione, quello di cui hai veramente bisogno è eseguire ALTER PROCEDURE per attivare un'analisi del suo testo e una validazione dello schema (le cose sono un po' diverse in T-SQL rispetto al tuo solito linguaggio ciclo di compilazione/esecuzione, la 'compilazione' di per sé si verifica solo quando la procedura viene effettivamente eseguita). Puoi iniziare scorrendo il sys.sql_dependencies per trovare tutte le dipendenze dell'oggetto alterato e anche la "definizione del modulo" delle dipendenze da sys.sql_modules :

with cte_dep as (
   select object_id
      from sys.sql_dependencies
    where referenced_major_id = object_id('<your altered object name>') 
    union all
    select d.object_id
    from sys.sql_dependencies d
        join cte_dep r on d.referenced_major_id = r.object_id
    )
, cte_distinct as (
    select distinct object_id
        from cte_dep)
select object_name(c.object_id)
    , c.object_id 
    , m.definition
    from cte_distinct c
    join sys.sql_modules m on c.object_id = m.object_id

È quindi possibile eseguire i "moduli" dipendenti e ricrearli (ad es. rilasciarli ed eseguire il codice nella "definizione"). Si noti che un "modulo" è più generico di una stored procedure e copre anche visualizzazioni, trigger, funzioni, regole, impostazioni predefinite e filtri di replica. I 'moduli' crittografati non avranno definizione la definizione disponibile e per essere assolutamente corretti devi anche tenere conto delle varie impostazioni catturate in sys.sql_modules (ansi nulls, associazione dello schema, esecuzione come clausole ecc.).

Se utilizzi SQL dinamico, non è possibile verificarlo. Non verrà catturato da sys.sql_dependencies , né verrà convalidato 'ricreando' il modulo.

Nel complesso, penso che la tua migliore opzione, con un ampio margine, sia implementare la convalida degli unit test.