Ik begrijp uw vraag als 'wanneer ik een schemawijziging aanbreng, wil ik alle procedures valideren die ze nog steeds correct uitvoeren met het nieuwe schema'. D.w.z. als u een kolom laat vallen waarnaar wordt verwezen in een SELECT in een procedure, dan wilt u dat deze wordt gemarkeerd omdat er wijzigingen voor nodig zijn. Dus specifiek begrijp ik uw vraag niet als 'Ik wil dat de procedure opnieuw wordt gecompileerd bij de volgende uitvoering', omdat die taak voor u wordt uitgevoerd door de engine, die de wijziging van de metadataversie zal detecteren die is gekoppeld aan een schemawijziging en de bestaande weggooit uitvoeringsplannen in de cache.
Mijn eerste observatie is dat wat je beschrijft in je vraag meestal de taak is van een TEST en u zou een QA-stap in uw implementatieproces moeten hebben die de nieuwe 'build' valideert. De beste oplossing die u zou kunnen hebben, is het implementeren van een minimale set eenheidstests die op zijn minst al uw opgeslagen procedures doorlopen en de uitvoering valideren. van elk op juistheid, in een testimplementatie. Dat zou vrijwel alle verrassingen elimineren, in ieder geval elimineren waar het pijn doet (in de productie of bij de klant).
Uw volgende beste optie is om te vertrouwen op uw ontwikkeltools om deze afhankelijkheden bij te houden. De Visual Studio Database 2008 Database Edition biedt dergelijke functionaliteit kant-en-klaar en zorgt ervoor dat elke wijziging die u in het schema aanbrengt, wordt gevalideerd.
En tot slot is uw laatste optie om iets te doen dat lijkt op wat KM voorstelde:een iteratie automatiseren door al uw procedures, afhankelijk van het gewijzigde object (en alle procedures afhankelijk van de afhankelijke, enzovoort, enzovoort). Het is niet voldoende om de procedures voor hercompilatie te markeren, wat u echt nodig hebt, is om de ALTER-PROCEDURE uit te voeren om een parsering van de tekst en een validatie van het schema te activeren (dingen zijn een beetje anders in T-SQL versus uw gebruikelijke taal compile/execute-cyclus, de 'compilatie' op zich vindt alleen plaats wanneer de procedure daadwerkelijk wordt uitgevoerd). U kunt beginnen door de sys.sql_dependencies
om alle afhankelijkheden van uw gewijzigde object te vinden, en ook de 'moduledefinitie' van de afhankelijkheden te vinden van 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
U kunt dan de afhankelijke 'modules' doorlopen en ze opnieuw maken (d.w.z. ze laten vallen en de code in de 'definitie' uitvoeren). Merk op dat een 'module' generieker is dan een opgeslagen procedure en ook weergaven, triggers, functies, regels, standaardinstellingen en replicatiefilters omvat. Versleutelde 'modules' hebben geen definitie die beschikbaar is en om absoluut correct te zijn, moet u ook rekening houden met de verschillende instellingen die zijn vastgelegd in sys.sql_modules
(ansi nulls, schemabinding, execute as-clausules enz.).
Als u ynamic SQL gebruikt, kan dat niet worden geverifieerd. Het wordt niet vastgelegd door sys.sql_dependencies
, en het wordt ook niet gevalideerd door de module 'opnieuw te maken'.
Over het algemeen denk ik dat uw beste optie, met een ruime marge, is om de validatie van unit-tests te implementeren.