Jak mogę wykryć uszkodzone procedury przechowywane po zmianie schematu?

11

Zmodyfikowałem centralną tabelę w mojej bazie danych, a sp_depends dosłownie zwraca setki wyników, i obawiam się, że niektóre z tych procedur przechowywanych mogą się nie kompilować po mojej zmianie.

Sprawdzanie jednej procedury składowanej jest łatwe (po prostu ponownie uruchamiam skrypt alter i sprawdzam, czy operacja się powiodła), ale robienie tego na ponad 100 procedurach jest nieco kłopotliwe.

Wiem, że mogę użyć skryptu takiego jak ten, aby ponownie skompilować wszystkie obiekty mojej bazy danych, ale faktyczna operacja odbędzie się następnym razem, gdy procedura składowana zostanie wykonana, nie natychmiast, więc w moim przypadku nie wydaje się to właściwe.

Myślałem również, że mogę całkowicie usunąć wszystkie procedury składowane i ponownie zhomonizować moją bazę danych za pomocą mojego systemu kontroli źródła, ale ta opcja, choć wykonalna, nie jest zbyt elegancka. Czy jest na to lepszy sposób?

Używam SQLServer 2008 R2, a moje skrypty bazy danych są przechowywane w projekcie bazy danych VS 2008.


Aby to wyjaśnić, nie zalecam, aby polegać wyłącznie na tym podejściu do kodu testowego. Dokładnie tak jak w c # natychmiast wykrywasz błąd składniowy w innych zależnych plikach podczas kodowania (a następnie używasz innych strategii do testowania, takich jak testy jednostkowe, które zwykle są o kilka rzędów wielkości wolniejsze), myślę, że sensowne byłoby wykrycie zależności SQL błędy w sekundach zamiast przeprowadzania pełnego testu funkcjonalnego, który zwykle zajmuje kilka godzin.

Brann
źródło

Odpowiedzi:

7

Co powiesz na przeprowadzenie testów jednostkowych, funkcjonalnych, integracyjnych i wydajnościowych? Jeśli nie masz żadnych testów, powinieneś zacząć traktować schemat bazy danych jako kod i traktować go jako taki, w tym kontrolę wersji i testowanie. Alex Kuznetsov ma całą książkę poświęconą temu tematowi: Defensive Database Programming with SQL Server .

Remus Rusanu
źródło
Testy nie zawsze obejmują 100% kodu, a kiedy to robią, zwykle trwają kilka godzin. W języku c # mogę wykryć, czy mój kod nadal się kompiluje w ciągu kilku sekund (niezależnie od jego poprawności). Nie oznacza to, że powinienem wepchnąć kod (bez względu na to, czy jest to kod c # lub PLSQL) do produkcji bez odpowiedniego testowania, ale nie wydaje się nierozsądne, aby mieć sposób na szybkie wykrycie zepsutych zależności, prawda?
Brann
2
Niestety, obecny stan SQL Server w zakresie wykrywania zależności w procedurze przechowywanej jest „głęboko zepsuty”, patrz Zrozumienie zależności SQL lub Aktualizowanie sysdepends w SQL Server 2008 . Istnieją nawet narzędzia innych firm, które próbują rozwiązać ten problem
Remus Rusanu
2
To sprawia, że ​​testy jednostkowe / funkcjonalne są praktycznie jedynym niezawodnym sposobem wykrywania przełomowych zmian.
Remus Rusanu,
1
W celu szybkiego sprawdzenia Visual Studio Database Projects wykonuje całkiem przyzwoitą pracę przy sprawdzaniu poprawności każdej zmiany.
Remus Rusanu,
4

Jest to obejście, ale możesz wygenerować skrypty UTWÓRZ PROCEDURĘ dla bazy danych (baza danych prawym przyciskiem myszy -> zadania -> wygeneruj skrypty), znaleźć i zastąpić UTWÓRZ PROCEDURĘ ALTER PROCEDURE, a następnie parsować.

Mam nadzieję, że uzyskasz lepszą odpowiedź tutaj - ja też jestem zainteresowany! :)

JHFB
źródło
Nie zaznaczam twojej odpowiedzi jako zaakceptowanej, ponieważ wciąż mam nadzieję na czystsze rozwiązanie (mam nadzieję, że możliwe do skryptu), ale na pewno dostaniesz moje +1! Dzięki.
Brann,
3
To podejście nie da ci znać, jeśli odwołujesz się do nieistniejącej tabeli .
Nick Chammas
To podejście również nie zadziała, jeśli wygenerowany skrypt jest większy niż około 30 000 linii. Nienawidzę, że to wiem ...
Eonasdan
3

Możesz użyć narzędzia Sql Server Data Tools (SSDT). Microsoft Visual Studio umożliwia utworzenie projektu Sql Server. Następnie importuje się bazę danych do projektu, a następnie buduje projekt. Jeśli są jakieś uszkodzone procedury składowane lub obiekty, pojawi się błąd kompilacji.

VenVig
źródło
Dodam, że możesz łatwo wygenerować nowy skrypt tworzenia bazy danych z projektu SSDT i uruchomić w środowisku testowym, co będzie dość dokładną weryfikacją, czy procs / wyzwalacze / etc nie są uszkodzone z powodu zmian schematu.
AaronLS,
3

Być może warto przyjrzeć się temu pytaniu SO. Szukam niezawodnego sposobu weryfikacji procedur przechowywanych T-SQL. Czy ktoś go ma? który pyta zasadniczo o to samo, z kilkoma odpowiedziami.

Aby zbudować na podstawie skryptu opublikowanego przez Alaa Awada ... powinien on pokazywać schemat i bazę danych obiektów odniesienia i odniesienia. Jeśli używasz wielu tabel temp za pośrednictwem aliasów (które czasami pojawiają się podczas używania sys.sql_expression_dependencies), parametrów UDTT lub innych dynamicznych funkcji, może być konieczne użycie funkcji sys.dm_sql_referenced_entitieslub sys.dm_sql_referencing_entitieszamiast / też.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]
Arkaine55
źródło
1
Należy dodać je do klauzuli WHERE: / * Nie istniejącego UserType / I sed.referenced_entity_name NOT IN (SELECT [nazwa] Z sys.types) / Not an alias * / I sed.referenced_schema_name IS NOT NULL
JasonBluefire
1

użyj sys.sql_expression_dependencies dodanych w SQL Server 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO
Alaa Awad
źródło
Może to być przydatne, jednak nie jest to tak proste, jak schemat musi również wziąć pod uwagę. Pojawiają się również problemy, w których sys.sql_expession_dependencies wyświetla używany alias, a nie rzeczywistą tabelę zależną, co oczywiście kończy się niepowodzeniem testu object_id (). Wreszcie wyświetla tabele zdefiniowane przez użytkownika przekazywane jako parametry do procedur przechowywanych - co nie jest tak naprawdę przydatne.
Tabloo Quijico