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

Genkompilere lagrede procs?

Jeg forstår dit spørgsmål som "når jeg foretager en skemaændring, vil jeg validere alle procedurer, som de stadig udfører korrekt med det nye skema". dvs. hvis du dropper en kolonne, der er refereret til i en SELECT i en procedure, så vil du have den markeret, da den kræver ændringer. Så specifikt forstår jeg ikke dit spørgsmål som "Jeg vil have, at proceduren skal rekompileres ved næste udførelse", da det job bliver taget hånd om for dig af motoren, som vil opdage metadataversionsændringen forbundet med enhver skemaændring og kassere den eksisterende cachelagrede udførelsesplaner.

Min første observation er, at det, du beskriver i dit spørgsmål, normalt er en TESTs opgave og du bør have et QA-trin i din implementeringsproces, der validerer den nye 'build'. Den bedste løsning, du kunne have, er at implementere et minimalt sæt enhedstests, som i det mindste gentager alle dine lagrede procedurer og validerer udførelsen af hver for korrekthed, i en testimplementering. Det ville stort set eliminere alle overraskelser, i det mindste eliminere dem, hvor det gør ondt (i produktionen eller hos kunden).

Din næstbedste mulighed er at stole på dine udviklingsværktøjer til at spore disse afhængigheder. Visual Studio Database 2008 Database Edition leverer en sådan funktionalitet ud af kassen, og den sørger for at validere enhver ændring, du foretager i skemaet.

Og endelig er din sidste mulighed at gøre noget, der ligner det, KM foreslog:automatiser en iteration gennem alle dine procedurer afhængigt af det ændrede objekt (og alle procedurer afhængigt af de afhængige og så videre og så videre rekursivt). Det vil ikke være tilstrækkeligt at markere procedurerne for rekompilering, det du virkelig har brug for er at køre ALTER PROCEDUREN for at udløse en parsing af dens tekst og en validering af skemaet (ting er lidt anderledes i T-SQL i forhold til dit sædvanlige sprog kompilering/udførelsescyklus, 'kompileringen' i sig selv forekommer kun, når proceduren rent faktisk udføres). Du kan starte med at iterere gennem sys. sql_afhængigheder for at finde alle afhængigheder af dit ændrede objekt, og også finde 'moduldefinitionen' af afhængighederne fra 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

Du kan derefter køre gennem de afhængige 'moduler' og genskabe dem (dvs. slippe dem og køre koden i 'definitionen'). Bemærk, at et 'modul' er mere generisk end en lagret procedure og dækker også visninger, triggere, funktioner, regler, standardindstillinger og replikeringsfiltre. Krypterede 'moduler' vil ikke have definitionen til rådighed, og for at være helt korrekt skal du også tage højde for de forskellige indstillinger, der er optaget i sys.sql_modules (ansi nuller, skemabinding, eksekver som klausuler osv.).

Hvis du bruger ynamic SQL, kan det ikke verificeres. Det vil ikke blive fanget af sys.sql_dependencies , og det vil heller ikke blive valideret ved at 'genoprette' modulet.

Samlet set tror jeg, at din bedste mulighed, med stor margen, er at implementere enhedstestvalideringen.



  1. Oracle Transparent Data Encryption udekrypteret adgang

  2. Hvordan håndterer man valgfri parametre i SQL-forespørgsel?

  3. Udførelse af matematisk operation på midlertidig kolonne i SQL

  4. Den mest effektive måde at flytte tabelrækker fra en tabel til en anden