Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Rekompilować przechowywane procedury?

Rozumiem twoje pytanie jako „kiedy dokonuję zmiany schematu, chcę zweryfikować wszystkie procedury, które nadal wykonują poprawnie, z nowym schematem”. Tj. jeśli usuniesz kolumnę, do której odwołuje się SELECT w procedurze, chcesz ją oflagować, ponieważ wymaga zmian. Tak więc konkretnie nie rozumiem twojego pytania jako „Chcę, aby procedura została ponownie skompilowana przy następnym wykonaniu”, ponieważ to zadanie jest obsługiwane za ciebie przez silnik, który wykryje zmianę wersji metadanych powiązaną z jakąkolwiek zmianą schematu i odrzuci istniejące buforowane plany wykonania.

Moja pierwsza obserwacja jest taka, że ​​to, co opisujesz w swoim pytaniu, jest zwykle zadaniem TESTU i powinieneś mieć krok kontroli jakości w procesie wdrażania, który sprawdza poprawność nowej „kompilacji”. Najlepszym rozwiązaniem, jakie możesz mieć, jest zaimplementowanie minimalnego zestawu testów jednostkowych, które przynajmniej iterują wszystkie procedury składowane i weryfikują wykonywanie każdego z nich pod kątem poprawności, we wdrożeniu testowym. To praktycznie wyeliminowałoby wszystkie niespodzianki, a przynajmniej wyeliminowałoby je tam, gdzie boli (w produkcji lub u klienta).

Kolejną najlepszą opcją jest poleganie na narzędziach programistycznych do śledzenia tych zależności. Visual Studio Database 2008 Database Edition zapewnia taką funkcjonalność po wyjęciu z pudełka i zadba o walidację wszelkich zmian wprowadzonych w schemacie.

I wreszcie ostatnią opcją jest zrobienie czegoś podobnego do tego, co sugerował KM:zautomatyzować iterację wszystkich procedur w zależności od zmodyfikowanego obiektu (i wszystkich procedur zależnych od tych zależnych itd. i tak dalej rekurencyjnie). Nie wystarczy oznaczyć procedury rekompilacji, naprawdę potrzebujesz uruchomić PROCEDURĘ ALTER, aby uruchomić parsowanie tekstu i walidację schematu (w T-SQL jest trochę inaczej niż w Twoim zwykłym języku kompilacji/wykonania, sama kompilacja występuje tylko wtedy, gdy procedura jest faktycznie wykonywana). Możesz zacząć od iteracji przez sys.sql_dependencies aby znaleźć wszystkie zależności zmienionego obiektu, a także znaleźć „definicję modułu” zależności z 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

Następnie możesz przejść przez zależne 'moduły' i ponownie je utworzyć (tj. usunąć je i uruchomić kod w 'definicji'). Należy zauważyć, że „moduł” jest bardziej ogólny niż procedura składowana i obejmuje również widoki, wyzwalacze, funkcje, reguły, wartości domyślne i filtry replikacji. Zaszyfrowane 'moduły' nie będą miały definicji dostępnej definicji i aby być absolutnie poprawnym, musisz również uwzględnić różne ustawienia przechwycone w sys.sql_modules (null ansi, wiązanie schematu, wykonywanie jako klauzule itp.).

Jeśli używasz dynamicznego SQL, nie można tego zweryfikować. Nie zostanie przechwycony przez sys.sql_dependencies , ani nie zostanie to zweryfikowane przez „odtworzenie” modułu.

Ogólnie myślę, że najlepszą opcją, z dużym marginesem, jest wdrożenie walidacji testów jednostkowych.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego T-SQL ISNULL() obcina ciąg, a COALESCE nie?

  2. SQL CASE i zmienne lokalne

  3. Jak wyświetlić rekord wiele razy, w tym interwały dzienne w oparciu o daty rozpoczęcia i zakończenia?

  4. Odniesienie do aliasu kolumny w klauzuli WHERE

  5. T-SQL Usuwa wszystkie wiersze z tabeli, gdy podzapytanie jest zniekształcone