Wie kann ich fehlerhafte gespeicherte Prozeduren nach einer Schemaänderung erkennen?

11

Ich habe eine zentrale Tabelle in meiner Datenbank geändert und sp_depends gibt buchstäblich Hunderte von Ergebnissen zurück. Ich befürchte, dass einige dieser gespeicherten Prozeduren nach meiner Änderung möglicherweise nicht mehr kompiliert werden.

Das Überprüfen einer einzelnen gespeicherten Prozedur ist einfach (ich führe nur das Änderungsskript erneut aus und prüfe, ob der Vorgang erfolgreich ist), aber dies bei mehr als 100 Prozeduren zu tun, ist etwas umständlich.

Ich weiß, dass ich ein Skript wie dieses verwenden kann, um alle Objekte meiner Datenbank neu zu kompilieren, aber der eigentliche Vorgang wird beim nächsten Ausführen der gespeicherten Prozedur nicht sofort ausgeführt, sodass dies in meinem Fall nicht angemessen erscheint.

Ich dachte auch, dass ich alle gespeicherten Prozeduren insgesamt löschen und meine Datenbank mit meinem Quellcodeverwaltungssystem neu synchronisieren könnte, aber diese Option ist zwar praktikabel, aber nicht sehr elegant. Gibt es einen besseren Weg, dies zu tun?

Ich verwende SQLServer 2008 R2 und meine Datenbankskripte werden in einem VS 2008-Datenbankprojekt gespeichert.


Zur Verdeutlichung befürworte ich nicht, dass man sich beim Testen von Code ausschließlich auf diesen Ansatz verlassen sollte. Genau wie in c # erkennen Sie beim Codieren sofort Syntaxfehler in anderen abhängigen Dateien (und verwenden dann andere Teststrategien, z. B. Unit-Tests, die normalerweise mehrere Größenordnungen langsamer sind). Ich halte es für sinnvoll, SQL-Abhängigkeiten zu erkennen Fehler in Sekunden, anstatt einen vollständigen Funktionstest durchführen zu müssen, der in der Regel einige Stunden dauern kann.

Brann
quelle

Antworten:

7

Wie wäre es, wenn Sie Ihre Geräte-, Funktions-, Integrations- und Leistungstests durchführen? Wenn Sie keine Tests haben, ist es an der Zeit, Ihr Datenbankschema als Code zu betrachten und als solchen zu behandeln, einschließlich Versionskontrolle und Testen. Alex Kuznetsov hat ein ganzes Buch zu diesem Thema: Defensive Datenbankprogrammierung mit SQL Server .

Remus Rusanu
quelle
Tests decken nicht immer 100% des Codes ab, und wenn dies der Fall ist, dauert die Ausführung in der Regel einige Stunden. In c # kann ich in Sekundenschnelle feststellen, ob mein Code noch kompiliert wird (unabhängig von seiner Richtigkeit). Dies bedeutet nicht, dass ich Code (unabhängig davon, ob es sich um c # oder PLSQL handelt) in die Produktion bringen sollte, ohne ihn ordnungsgemäß zu testen, aber es erscheint nicht unangemessen, eine Möglichkeit zu haben , defekte Abhängigkeiten schnell zu erkennen, oder?
Brann
2
Leider ist der derzeitige Stand der Technik in Bezug auf die Erkennung von Abhängigkeiten in gespeicherten Prozeduren "stark fehlerhaft ", siehe Grundlegendes zu SQL-Abhängigkeiten oder Aktualisieren von Systemabhängigkeiten in SQL Server 2008 . Es gibt sogar Tools von Drittanbietern, die versuchen, das Problem zu
beheben
2
Dies macht Unit- / Funktionstests so ziemlich zum einzigen zuverlässigen Weg, um Bruchänderungen zu erkennen.
Remus Rusanu
1
Für eine schnelle Überprüfung leisten die Visual Studio-Datenbankprojekte einen recht guten Job bei der Validierung von Änderungen.
Remus Rusanu
4

Es ist eine Problemumgehung, aber Sie können die CREATE PROCEDURE-Skripte für die Datenbank generieren (Rechtsklick auf Datenbank -> Aufgaben -> Generieren von Skripten), CREATE PROCEDURE suchen und durch ALTER PROCEDURE ersetzen und dann analysieren.

Ich hoffe du bekommst hier eine bessere Antwort - ich bin auch interessiert! :) :)

JHFB
quelle
Ich markiere Ihre Antwort nicht als akzeptiert, weil ich immer noch auf eine sauberere Lösung hoffe (hoffentlich eine skriptfähige), aber Sie erhalten definitiv meine +1! Vielen Dank.
Brann
3
Dieser Ansatz informiert Sie nicht, wenn Sie auf eine nicht vorhandene Tabelle verweisen .
Nick Chammas
Dieser Ansatz funktioniert auch nicht, wenn das generierte Skript größer als 30.000 Zeilen ist. Ich hasse es, dass ich das weiß ..
Eonasdan
3

Sie können SQL Server Data Tools (SSDT) ​​verwenden. Mit Microsoft Visual Studio können Sie ein SQL Server-Projekt erstellen. Man importiert dann die Datenbank in das Projekt und erstellt dann das Projekt. Wenn fehlerhafte gespeicherte Prozeduren oder Objekte vorhanden sind, wird ein Kompilierungsfehler angezeigt.

VenVig
quelle
Ich möchte hinzufügen, dass Sie auf einfache Weise ein neues Datenbankerstellungsskript aus dem SSDT-Projekt generieren und in einer Testumgebung ausführen können. Dies ist eine ziemlich gründliche Überprüfung, dass keine Procs / Trigger / etc aufgrund von Schemaänderungen fehlerhaft sind.
AaronLS
3

Vielleicht möchten Sie sich diese SO-Frage ansehen. Ich suche nach einer zuverlässigen Möglichkeit, gespeicherte T-SQL-Prozeduren zu überprüfen. Hat jemand einen? das fragt im Wesentlichen das gleiche, mit mehreren Antworten.

Um auf dem von Alaa Awad veröffentlichten Skript aufzubauen, sollte dies das Schema und die Datenbank der referenzierten und referenzierenden Objekte anzeigen. Wenn Sie viele temporäre Tabellen über Aliase (die manchmal bei der Verwendung sys.sql_expression_dependenciesangezeigt werden ), UDTT-Parameter oder andere dynamische Funktionen verwenden, müssen Sie möglicherweise die Funktionen sys.dm_sql_referenced_entitiesoder sys.dm_sql_referencing_entitiesstattdessen / auch verwenden.

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
quelle
1
Sollte diese zur where-Klausel hinzufügen: / * Kein vorhandener Benutzertyp / AND sed.referenced_entity_name NOT IN (SELECT [name] FROM sys.types) / Kein Alias ​​* / AND sed.referenced_schema_name IST NICHT NULL
JasonBluefire
1

Verwenden Sie die in SQL Server 2008 hinzugefügten sys.sql_expression_dependencies

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
quelle
Dies kann nützlich sein, ist jedoch nicht so einfach, da das Schema ebenfalls berücksichtigt werden muss. Ich bekomme auch Probleme, bei denen sys.sql_expession_dependencies den verwendeten Alias ​​anstelle der tatsächlich abhängigen Tabelle anzeigt, was den Test object_id () offensichtlich nicht besteht. Schließlich werden benutzerdefinierte Tabellen angezeigt, die als Parameter an gespeicherte Prozeduren übergeben werden - was nicht wirklich nützlich ist.
Tabloo Quijico