sql >> Databasteknik >  >> RDS >> Sqlserver

Kompilera om lagrade processer?

Jag förstår din fråga som "när jag gör en schemaändring vill jag validera alla procedurer som de fortfarande kör korrekt med det nya schemat". Dvs. om du släpper en kolumn som refereras till i en SELECT i en procedur, vill du att den ska flaggas eftersom den kräver ändringar. Så specifikt förstår jag inte din fråga som "Jag vill att proceduren ska kompileras om vid nästa körning", eftersom det jobbet sköts åt dig av motorn, som kommer att upptäcka metadataversionsändringen som är kopplad till alla schemaändringar och kassera den befintliga cachade utförandeplaner.

Min första observation är att det du beskriver i din fråga vanligtvis är jobbet för ett TEST och du bör ha ett QA-steg i din distributionsprocess som validerar den nya "builden". Den bästa lösningen du kan ha är att implementera en minimal uppsättning enhetstester som åtminstone upprepar alla dina lagrade procedurer och validerar exekveringen av varje för korrekthet, i en testinstallation. Det skulle i stort sett eliminera alla överraskningar, åtminstone eliminera dem där det gör ont (i produktionen eller hos kunden).

Ditt näst bästa alternativ är att lita på dina utvecklingsverktyg för att spåra dessa beroenden. Visual Studio Database 2008 Database Edition tillhandahåller sådan funktionalitet direkt och det kommer att ta hand om att validera alla ändringar du gör i schemat.

Och slutligen är ditt sista alternativ att göra något liknande det som KM föreslog:automatisera en iteration genom alla dina procedurer beroende på det modifierade objektet (och alla procedurer beroende på de beroende och så vidare och så vidare rekursivt). Det räcker inte att markera procedurerna för omkompilering, det du verkligen behöver är att köra ALTER PROCEDUREN för att utlösa en analys av dess text och en validering av schemat (saker är lite annorlunda i T-SQL jämfört med ditt vanliga språk kompilerings-/körcykeln, "kompileringen" i sig sker endast när proceduren faktiskt körs). Du kan börja med att iterera genom sys. sql_dependencies för att hitta alla beroenden för ditt ändrade objekt, och även hitta "moduldefinitionen" för beroenden från 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 sedan köra igenom de beroende 'modulerna' och återskapa dem (dvs släppa dem och köra koden i 'definitionen'). Observera att en "modul" är mer generisk än en lagrad procedur och täcker även vyer, triggers, funktioner, regler, standardinställningar och replikeringsfilter. Krypterade 'moduler' kommer inte att ha definitionen som är tillgänglig och för att vara helt korrekt måste du också ta hänsyn till de olika inställningarna som registrerats i sys.sql_modules (ansi-nullvärden, schemabindning, exekvera som klausuler etc).

Om du använder ynamic SQL kan det inte verifieras. Det kommer inte att fångas upp av sys.sql_dependencies , och det kommer inte att valideras genom att "återskapa" modulen.

Sammantaget tror jag att ditt bästa alternativ, med stor marginal, är att implementera enhetstestervalideringen.



  1. MySQL union och beställa med hjälp

  2. Långsam platsbaserad sökresultatfråga

  3. WordPress förberett uttalande med IN()-villkor

  4. välj en slumpmässig rad med komplex filtrering