Freigeben über


Verbesserungen bei der Behandlung einiger Datentypen und ungewöhnlicher Vorgänge in SQL Server und Azure SQL-Datenbank

In diesem Artikel wird erläutert, wie beibehaltene Strukturen in Ihrer SQL Server-Datenbank als Teil der Upgradekompatibilitätsstufe überprüft werden können und wie alle betroffenen Strukturen nach dem Upgrade der Kompatibilitätsstufe neu erstellt werden können.

Originalproduktversion: SQL Server 2017, SQL Server 2016
Ursprüngliche KB-Nummer: 4010261

Das Datenbankmodul in Microsoft SQL Server 2016 und Azure SQL-Datenbank umfasst Verbesserungen bei Datentypkonvertierungen und mehreren anderen Vorgängen. Die meisten dieser Verbesserungen bieten eine höhere Genauigkeit, wenn Sie mit Gleitkommatypen und auch mit klassischen Datetime-Typen arbeiten.

Diese Verbesserungen sind alle verfügbar, wenn Sie mindestens 130 Datenbankkompatibilitätsstufe verwenden. Dies bedeutet, dass bei einigen (meist ungewöhnlichen) Ausdrücken verschiedene Ergebnisse für einige Eingabewerte angezeigt werden, nachdem Sie die Datenbank auf Kompatibilitätsebene 130 oder eine höhere Einstellung aktualisiert haben. Diese Ergebnisse können sich in folgenden Ergebnissen widerspiegeln:

  • Beibehaltene Strukturen in der Datenbank
  • eingeschlossene Tabellendaten, die Einschränkungen unterliegen CHECK
  • Persistente berechnete Spalten
  • Indizes, die auf berechnete Spalten verweisen
  • gefilterte Indizes und indizierte Ansichten.

Wenn Sie über eine Datenbank verfügen, die in einer früheren Version von SQL Server erstellt wurde, empfehlen wir, nach dem Upgrade auf SQL Server 2016 oder höher zusätzliche Überprüfungen durchzuführen, und bevor Sie die Datenbankkompatibilitätsstufe ändern.

Wenn Sie feststellen, dass eine der dauerhaften Strukturen in Ihrer Datenbank von diesen Änderungen betroffen ist, empfehlen wir, betroffene Strukturen nach dem Upgrade der Datenbankkompatibilitätsstufe neu zu erstellen. Dadurch profitieren Sie von diesen Verbesserungen in SQL Server 2016 oder höher.

In diesem Artikel wird beschrieben, wie beibehaltene Strukturen in Ihrer Datenbank als Teil des Upgrades auf Kompatibilitätsebene 130 oder höher überprüft werden können und wie alle betroffenen Strukturen neu erstellt werden können, nachdem Sie die Kompatibilitätsstufe geändert haben.

Überprüfungsschritte während eines Upgrades auf Datenbankkompatibilitätsstufe

Ab SQL Server 2016 umfassen SQL Server und Azure SQL-Datenbank Verbesserungen an der Genauigkeit der folgenden Vorgänge:

  • Ungewöhnliche Datentypkonvertierungen. Dazu gehören folgendes:
    • Float/integer to/from datetime/smalldatetime
    • Real/float to/from numeric/money/smallmoney
    • Float to real
  • Einige Fälle von DATEPART/DATEDIFF und DEGREES
  • CONVERT die eine NULL Formatvorlage verwendet

Um diese Verbesserungen für die Ausdrucksauswertung in Ihrer Anwendung zu verwenden, ändern Sie die Kompatibilitätsebene Ihrer Datenbanken in 130 (für SQL Server 2016) oder 140 (für SQL Server 2017 und Azure SQL-Datenbank). Weitere Informationen zu allen Änderungen und einigen Beispielen, die die Änderungen zeigen, finden Sie im Abschnitt "Anhang A ".

Die folgenden Strukturen in der Datenbank können die Ergebnisse eines Ausdrucks beibehalten:

  • Tabellendaten, die CHECK einschränkungen unterliegen
  • Gespeicherte berechnete Spalten
  • Indizes, die berechnete Spalten im Schlüssel oder enthaltene Spalten verwenden
  • Gefilterte Indizes
  • Indizierte Sichten

Nehmen Sie das folgende Szenario als Beispiel:

  • Sie verfügen über eine Datenbank, die von einer früheren Version von SQL Server erstellt wurde oder die bereits in SQL Server 2016 oder einer höheren Version erstellt wurde, jedoch auf Kompatibilitätsebene 120 oder einer früheren Ebene.

  • Sie verwenden alle Ausdrücke, deren Genauigkeit im Rahmen der Definition beibehaltener Strukturen in Ihrer Datenbank verbessert wurde.

In diesem Szenario haben Sie möglicherweise beibehaltene Strukturen, die von den Verbesserungen der Genauigkeit betroffen sind, die mithilfe der Kompatibilitätsebene 130 oder höher implementiert werden. Wenn dies der Fall ist, empfehlen wir, die dauerhaften Strukturen zu überprüfen und alle betroffenen Strukturen neu zu erstellen.

Wenn Sie betroffene Strukturen haben und sie nach dem Ändern der Kompatibilitätsstufe nicht neu erstellen, können geringfügig andere Abfrageergebnisse auftreten. Die Ergebnisse hängen davon ab, ob ein bestimmter Index, eine berechnete Spalte oder ansicht verwendet wird und ob Daten in einer Tabelle als Verletzung einer Einschränkung angesehen werden könnten.

Notiz

Ablaufverfolgungskennzeichnung 139 in SQL Server

Das globale Ablaufverfolgungskennzeichen 139 wird in SQL Server 2016 CU3 und Service Pack (SP) 1 eingeführt, um die korrekte Konvertierungsemantik im Bereich der DBCC-Überprüfungsbefehle wie DBCC CHECKDB, DBCC CHECKTABLEzu erzwingen, und DBCC CHECKCONSTRAINTS wenn Sie die verbesserte Genauigkeits- und Konvertierungslogik analysieren, die mit Kompatibilitätsebene 130 in einer Datenbank eingeführt wurde, die eine frühere Kompatibilitätsstufe aufweist.

Warnung

Die Ablaufverfolgungskennzeichnung 139 soll nicht kontinuierlich in einer Produktionsumgebung aktiviert werden und sollte nur zum Zweck der Durchführung der in diesem Artikel beschriebenen Datenbanküberprüfungen verwendet werden. Daher sollte sie in dbcc traceoff (139, -1) derselben Sitzung deaktiviert werden, nachdem die Überprüfungsprüfungen abgeschlossen wurden.

Ablaufverfolgungskennzeichnung 139 wird ab SQL Server 2016 CU3 und SQL Server 2016 SP1 unterstützt.

Führen Sie die folgenden Schritte aus, um die Kompatibilitätsstufe zu aktualisieren:

  1. Führen Sie eine Überprüfung durch, um alle betroffenen dauerhaften Strukturen zu identifizieren:
    1. Aktivieren Sie das Ablaufverfolgungskennzeichnung 139 durch Ausführen DBCC TRACEON(139, -1).
    2. Ausführen DBCC CHECKDB/TABLE und CHECKCONSTRAINTS Befehle.
    3. Deaktivieren Sie die Ablaufverfolgungskennzeichnung 139 durch Ausführen DBCC TRACEOFF(139, -1).
  2. Ändern Sie die Datenbankkompatibilitätsebene auf 130 (für SQL Server 2016) oder 140 (für SQL Server 2017 und Azure SQL-Datenbank).
  3. Erstellen Sie alle Strukturen neu, die Sie in Schritt 1 identifiziert haben.

Notiz

Ablaufverfolgungskennzeichnungen in Azure SQL-Datenbank Festlegen von Ablaufverfolgungskennzeichnungen werden in Azure SQL-Datenbank nicht unterstützt. Daher müssen Sie die Kompatibilitätsstufe ändern, bevor Sie die Überprüfung durchführen:

  1. Aktualisieren Sie die Datenbankkompatibilitätsstufe auf 140.
  2. Überprüfen Sie, ob alle betroffenen dauerhaften Strukturen identifiziert werden.
  3. Erstellen Sie die Strukturen neu, die Sie in Schritt 2 identifiziert haben.
  • Anhang A enthält eine detaillierte Liste aller Genauigkeitsverbesserungen und bietet ein Beispiel für jede.

  • Anhang B enthält einen detaillierten Schritt-für-Schritt-Prozess zur Überprüfung und zum Neuerstellen betroffener Strukturen.

  • Anhang C und Anhang D enthalten Skripts zum Anheften potenziell betroffener Objekte in der Datenbank. Daher können Sie Ihre Überprüfungen einschränken und entsprechende Skripts generieren, um die Prüfungen auszuführen. Führen Sie das Skript in Anhang D aus, um am einfachsten zu ermitteln, ob beibehaltene Strukturen in Ihren Datenbanken von den Genauigkeitsverbesserungen der Kompatibilitätsebene 130 betroffen sind, um die korrekten Überprüfungen zu generieren, und führen Sie dann dieses Skript aus, um die Überprüfung durchzuführen.

Anhang A: Änderungen der Kompatibilitätsstufe 130

Dieser Anhang enthält detaillierte Listen der Verbesserungen der Ausdrucksauswertung in Kompatibilitätsebene 130. Jede Änderung enthält eine zugeordnete Beispielabfrage. Die Abfragen können verwendet werden, um die Unterschiede zwischen der Ausführung in einer Datenbank anzuzeigen, die eine Kompatibilitätsstufe vor 130 im Vergleich zu einer Datenbank verwendet, die Kompatibilitätsebene 130 verwendet.

In den folgenden Tabellen werden Datentypkonvertierungen und zusätzliche Vorgänge aufgeführt.

Datentypkonvertierungen

Von An Change Beispielabfrage Ergebnis für Kompatibilitätsebene < 130 Ergebnis für Kompatibilitätsebene = 130
float, real, numeric, decimal, money oder smallmoney datetime oder smalldatetime Erhöhen Sie die Rundungsgenauigkeit. Zuvor wurden Tag und Uhrzeit separat konvertiert, und die Ergebnisse wurden abgeschnitten, bevor Sie sie kombiniert haben. DECLARE @f FLOAT = 1.2 DECLARE @d DATETIME = @f SELECT CAST(@d AS FLOAT) 1.19999996141975 1.2
datetime bigint, int, or smallint Eine negative Datumstime, deren Zeitteil genau ein halber Tag ist oder in einem Tick eines halben Tages falsch gerundet wird (das Ergebnis ist um 1). DECLARE @h DATETIME = -0.5 SELECT @h, CAST(@h AS INT) 0 -1
datetime oder smalldatetime float, real, numeric, money, or smallmoney Verbesserte Genauigkeit für die letzten 8 Bits genauigkeit in einigen Fällen. DECLARE @p0 DATETIME = '1899-12-31 23:58:00.470' DECLARE @f FLOAT = CONVERT(FLOAT, @p0) SELECT @f, CAST(@f AS VARBINARY(8)) -0.00138344907407406, 0xBF56AA9B21D85800 -0.00138344907407407, 0xBF56AA9B21D8583B
float real Grenzprüfungen sind weniger streng. SELECT CAST (3.40282347000E+038 AS REAL) Arithmetischer Überlauf 3.402823E+38
numeric, money und smallmoney float Wenn die Eingabeskala null ist, gibt es eine rundende Ungenauigkeit, wenn Sie die vier Teile numerischer Elemente kombinieren. DECLARE @n NUMERIC(38, 0)= 41538374868278625639929991208632320 DECLARE @f FLOAT = CAST(@n AS FLOAT) SELECT CONVERT(BINARY(8), @f) 0x4720000000000000 0x4720000000000001
numeric, money und smallmoney float Wenn die Eingabeskala ungleich Null ist, gibt es eine rundende Ungenauigkeit, wenn Sie durch 10^-Skalierung dividieren. DECLARE @n NUMERIC(18, 10) = 12345678.0123456781 DECLARE @f FLOAT = CAST(@n AS FLOAT) SELECT CAST(@f AS BINARY(8)) 0x41678C29C06522C4 0x41678C29C06522C3
real oder float numeric Verbesserte Rundungsgenauigkeit in einigen Fällen. DECLARE @f float = 0.14999999999999999 SELECT CAST(@f AS numeric(1, 1)) 0.2 0.1
real oder float numeric Verbesserte Genauigkeit, wenn Sie in einigen Fällen auf mehr als 16 Ziffern runden. DECLARE @v decimal(38, 18) = 1E-18 SELECT @v 0.000000000000000000 0.000000000000000001
real oder float money oder smallmoney Verbesserte Genauigkeit beim Konvertieren großer Zahlen in einigen Fällen. DECLARE @f float = 2SET @f = POWER(@f, 49) + POWER(@f, -2) SELECT CAST(@f AS money) 562949953421312.2048 562949953421312.25
(n)(var)char numeric Eine Eingabe von mehr als 39 Zeichen löst nicht mehr notwendigerweise einen arithmetischen Überlauf aus. DECLARE @value nchar(100) = '1.11111111111111111111111111111111111111' SELECT CAST(@value AS decimal(2,1)) Arithmetischer Überlauf 1.1
(n)(var)char bit Unterstützt führende Leerzeichen und Zeichen. DECLARE @value nvarchar(100) = '1' SELECT CAST(@value AS bit) Fehler bei der Konvertierung beim Konvertieren des nvarchar Werts "1" in das Datentypbit. 1
datetime time oder datetime2 Verbesserte Genauigkeit beim Konvertieren in Datums-/Uhrzeittypen mit höherer Genauigkeit. Beachten Sie, dass Datetime-Werte als Teilstriche gespeichert werden, die 1/300 Sekunden darstellen. Die neueren Uhrzeit- und Datetime2-Typen speichern eine diskrete Anzahl von Ziffern, wobei die Anzahl der Ziffern mit der Genauigkeit übereinstimmt. DECLARE @value datetime = '1900-01-01 00:00:00.003' SELECT CAST(@value AS time(7)) 00:00:00.0030000 00:00:00.0033333
time oder datetime2 datetime Verbesserte Rundung in einigen Fällen. DECLARE @value time(4) = '00:00:00.0045' SELECT CAST(@value AS datetime) 1900-01-01 00:00:00.007 1900-01-01 00:00:00.003

Vorgang

Vorgang Change Beispielabfrage Ergebnis für Kompatibilitätsebene <130 Ergebnis für Kompatibilitätsebene 130
Verwenden Sie die RADIANS DEGREES integrierte Funktion, die den numerischen Datentyp verwendet. DEGREES Dividiert durch pi/180, wobei es zuvor mit 180/pi multipliziert wurde. Ähnlich für RADIANS. DECLARE @arg1 numeric = 1 SELECT DEGREES(@arg1) 57.295779513082323000 57.295779513082322865
Numerische Addition oder Subtraktion, wenn die Skalierung eines Operanden größer als die Skala des Ergebnisses ist. Das Runden tritt immer nach dem Additions- oder Subtraktionsvorgang auf, während es zuvor manchmal vorkommen konnte. DECLARE @p1 numeric(38, 2) = -1.15 DECLARE @p2 numeric(38, 1) = 10 SELECT @p1 + @p2 8,8 8,9
CONVERT mit NULL Stil. CONVERT mit NULL Formatvorlage wird immer zurückgegeben NULL , wenn der Zieltyp numerisch ist. SELECT CONVERT (SMALLINT, '0', NULL); 0 NULL
DATEPART die die Option "Mikrosekunden" oder "Nanosekunden" mit dem Datentyp "datetime" verwendet. Der Wert wird nicht mehr auf Millisekundenebene abgeschnitten, bevor er in Mikro- oder Nanosekunden konvertiert wird. DECLARE @dt DATETIME = '01-01-1900 00:00:00.003'; SELECT DATEPART(MICROSECOND, @dt); 3000 3.333
DATEDIFF die die Option "Mikrosekunden" oder "Nanosekunden" mit dem Datentyp "datetime" verwendet. Der Wert wird nicht mehr auf Millisekundenebene abgeschnitten, bevor er in Mikro- oder Nanosekunden konvertiert wird. DECLARE @d1 DATETIME = '1900-01-01 00:00:00.003' DECLARE @d2 DATETIME = '1900-01-01 00:00:00.007' SELECT DATEDIFF(MICROSECOND, @d1, @d2) 3000 3.333
Vergleich zwischen Datetime- und Datetime2-Werten mit Nichtzerowerten für Millisekunden. Der Datetime-Wert wird nicht mehr auf Millisekundenebene abgeschnitten, wenn Sie einen Vergleich mit einem Datetime2-Wert ausführen. Dies bedeutet, dass bestimmte Werte, die zuvor gleich verglichen wurden, nicht mehr gleich vergleichen. DECLARE @d1 DATETIME = '1900-01-01 00:00:00.003' DECLARE @d2 DATETIME2(3) = @d1 SELECT CAST(@d1 AS datetime2(7)), @d2SELECT CASE WHEN (@d1=@d2) THEN 'equal' ELSE 'unequal' END 1900-01-01 00:00:00:00.0030000, 1900-01-01 00:00:00.003 gleich 1900-01-01 00:00:00:00.0033333, 1900-01-01 00:00:00.003 ungleich
ROUND -Funktion, die den float Datentyp verwendet. Rundungsergebnisse unterscheiden sich. SELECT ROUND(CAST (-0.4175 AS FLOAT), 3) -0.418 -0.417

Anhang B: Schritte zum Überprüfen und Aktualisieren beibehaltener Strukturen

Es wird empfohlen, festzustellen, ob die Datenbank über permanente Strukturen verfügt, die von den Änderungen der Kompatibilitätsebene 130 betroffen sind, und dass Sie betroffene Strukturen neu erstellen.

Dies gilt nur für beibehaltene Strukturen, die in der Datenbank in einer älteren Version von SQL Server erstellt wurden, oder mithilfe einer Kompatibilitätsstufe, die niedriger als 130 ist. Die dauerhaften Strukturen, die potenziell betroffen sind, umfassen Folgendes:

  • Tabellendaten, die CHECK einschränkungen unterliegen
  • Gespeicherte berechnete Spalten
  • Indizes, die berechnete Spalten im Schlüssel oder enthaltene Spalten verwenden
  • Gefilterte Indizes
  • Indizierte Sichten

Führen Sie in diesem Fall das folgende Verfahren aus.

Schritt 1: Überprüfen der Datenbankkompatibilitätsstufe

  1. Überprüfen Sie die Kompatibilitätsstufe Ihrer Datenbank mithilfe der Prozedur, die in "Ansicht" dokumentiert ist, oder ändern Sie die Kompatibilitätsebene einer Datenbank.
  2. Wenn die Kompatibilitätsebene der Datenbank niedriger als 130 ist, empfehlen wir, die in Schritt 2 beschriebene Überprüfung durchzuführen, bevor Sie die Kompatibilitätsstufe auf 130 erhöhen.

Schritt 2: Identifizieren betroffener beibehaltener Strukturen

Ermitteln Sie, ob die Datenbank permanente Strukturen enthält, die von der verbesserten Genauigkeits- und Konvertierungslogik in Kompatibilitätsebene 130 in einer der folgenden Methoden betroffen sind:

  • DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS, die alle Strukturen in der Datenbank überprüft.
  • DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS, die die Strukturen im Zusammenhang mit einer einzelnen Tabelle überprüft.

Die Option WITH EXTENDED_LOGICAL_CHECKS ist erforderlich, um sicherzustellen, dass die dauerhaften Werte mit berechneten Werten verglichen werden, und um Fälle zu kennzeichnen, in denen ein Unterschied besteht. Da diese Prüfungen umfangreich sind, ist die Laufzeit von Anweisungen, die diese Option verwenden, länger als die Ausführung DBCC von DBCC Anweisungen ohne die Option. Daher empfiehlt DBCC CHECKTABLE es sich, einzelne Tabellen anzuheften.

DBCC CHECKCONSTRAINTS kann verwendet werden, um Einschränkungen zu überprüfen CHECK . Diese Anweisung kann entweder auf Datenbank- oder Tabellenebene verwendet werden.

DBCC CHECK Anweisungen sollten immer während eines Wartungsfensters ausgeführt werden, aufgrund der potenziellen Auswirkungen der Überprüfungen auf die Online-Workload.

Überprüfung auf Datenbankebene

Die Validierung auf Datenbankebene eignet sich für kleine und moderate Datenbanken. Verwenden Sie die Überprüfung auf Tabellenebene für große Datenbanken.

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS wird verwendet, um alle dauerhaften Strukturen in der Datenbank zu überprüfen.

DBCC CHECKCONSTRAINTS wird verwendet, um alle CHECK Einschränkungen in der Datenbank zu überprüfen.

DBCC CHECKCONSTRAINTS wird verwendet, um die Integrität von Einschränkungen zu überprüfen. Verwenden Sie das folgende Skript, um die Datenbank zu überprüfen:

USE [database_name]
GO
DBCC TRACEON(139, -1)
GO
DBCC CHECKCONSTRAINTS
GO
DBCC TRACEOFF(139, -1)
GO

Durch die Verwendung des Ablaufverfolgungskennzeichens wird sichergestellt, dass die Überprüfungen mithilfe der verbesserten Genauigkeits- und Konvertierungslogik durchgeführt werden, die sich in Kompatibilitätsebene 130 befindet, wodurch die richtige Konvertierungsemantik erzwungen wird, auch wenn die Datenbank über eine niedrigere Kompatibilitätsstufe verfügt.

Wenn die CHECKCONSTRAINTS Anweisung abgeschlossen ist und kein Resultset zurückgibt, ist keine zusätzliche Aktion erforderlich.

Wenn die Anweisung ein Resultset zurückgibt, gibt jede Zeile in den Ergebnissen eine Verletzung einer Einschränkung an und enthält auch die Werte, die gegen die Einschränkung verstoßen.

  • Speichern Sie die Namen der Tabellen und Einschränkungen zusammen mit den Werten, die den Verletzten verursacht haben (die WHERE Spalte im Resultset).

Das folgende Beispiel zeigt eine Tabelle mit einer CHECK Einschränkung und eine einzelne Zeile, die die Einschränkung unter niedrigeren Kompatibilitätsstufen erfüllt, die jedoch gegen die Einschränkung unter Kompatibilitätsebene 130 verstößt.

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=120
GO
CREATE TABLE dbo.table1
(
    c2 datetime,
    c3 datetime,
    c4 int,
    CONSTRAINT chk1 CHECK (c4= (DATEDIFF (ms, c2,c3)))
)
GO
INSERT dbo.table1 (c2, c3, c4) VALUES
(
    convert(datetime, '1900-01-01 00:00:00.997'),
    convert(datetime, '1900-01-01 00:00:01'), 3
)
GO
DBCC TRACEON(139, -1)
GO
DBCC CHECKCONSTRAINTS
GO
DBCC TRACEOFF(139, -1)
GO

Der CHECKCONSTRAINT Befehl gibt die folgenden Ergebnisse zurück.

Tabelle Einschränkung Hierbei gilt:
[dbo]. [Tabelle1] [chk1] [c2] = '1900-01-01 00:00:00.997' AND [c3] = '1900-01-01 00:00:01.000' AND [c4] = '3'

Dieses Ergebnis gibt an, dass die Einschränkung [chk1] für die Kombination von Spaltenwerten im Feld "Where" verletzt wird.

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS überprüft alle beibehaltenen Strukturen in der Datenbank. Dies ist die praktischste Option, da eine einzelne Anweisung alle Strukturen in der Datenbank überprüft. Diese Option eignet sich jedoch nicht für große Datenbanken aufgrund der erwarteten Laufzeit der Anweisung.

Verwenden Sie das folgende Skript, um die gesamte Datenbank zu überprüfen:

USE [database_name]
GO
DBCC TRACEON(139, -1)
GO
DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS, NO_INFOMSGS, TABLERESULTS
GO
DBCC TRACEOFF(139, -1)
GO

Durch die Verwendung des Ablaufverfolgungskennzeichens wird sichergestellt, dass die Überprüfungen mithilfe der verbesserten Genauigkeits- und Konvertierungslogik durchgeführt werden, die sich in Kompatibilitätsebene 130 befindet, wodurch die richtige Konvertierungsemantik erzwungen wird, auch wenn die Datenbank über eine niedrigere Kompatibilitätsstufe verfügt.

Wenn die CHECKDB Anweisung erfolgreich abgeschlossen wird, ist keine zusätzliche Aktion erforderlich.

Wenn die Anweisung mit Fehlern abgeschlossen ist, führen Sie die folgenden Schritte aus:

  1. Speichern Sie die Ergebnisse aus der Ausführung der DBCC Anweisung, die sich im Nachrichtenbereich in SQL Server Management Studio (SSMS) befindet, in einer Datei.
  2. Überprüfen, ob alle gemeldeten Fehler mit dauerhaften Strukturen zusammenhängen

Tabelle 1: Beibehaltene Strukturen und entsprechende Fehlermeldungen für Inkonsistenzen

Strukturtyp betroffen Beobachtete Fehlermeldungen Notieren Sie sich
Gespeicherte berechnete Spalten Msg 2537, Fehler der Ebene 16 Tabelle: Objekt-ID <object_id> , Index-ID <index_id> , . Fehler bei der Datensatzüberprüfung (gültige berechnete Spalte). Die Werte sind . object_id> und Index-ID index_id <<>
Indizes, die auf berechnete Spalten im Schlüssel verweisen oder spaltengefilterte Indizes enthalten Msg 8951-Tabellenfehler: Tabelle "<table_name>" (ID <object_id>). Die Datenzeile enthält keine übereinstimmende Indexzeile im Index "<index_name>" (ID <index_id>) And/oder Msg 8952 Table error: table '<table_name>' (ID <table_name>). Indexzeile in Index '' (ID <index_id>) stimmt nicht mit einer Datenzeile überein. Darüber hinaus können sekundäre Fehler 8955 und/oder 8956 auftreten. Dies enthält Details zu den genauen Zeilen, die betroffen sind. Dies kann für diese Übung ignoriert werden. object_id> und Index-ID index_id <<>
Indizierte Sichten Msg 8908 Die indizierte Ansicht "<view_name>" (Objekt-ID <object_id>) enthält nicht alle Zeilen, die die Ansichtsdefinition erzeugt. Und/oder Msg 8907 Die indizierte Ansicht "<view_name>" (Objekt-ID <object_id>) enthält Zeilen, die nicht von der Ansichtsdefinition erstellt wurden. Objekt-ID <object_id>

Wechseln Sie nach Abschluss der Überprüfung auf Datenbankebene zu Schritt 3.

Überprüfung auf Objektebene

Bei größeren Datenbanken ist es hilfreich, Strukturen und Einschränkungen für eine Tabelle oder eine Ansicht gleichzeitig zu überprüfen, um die Größe von Wartungsfenstern zu reduzieren oder die erweiterten logischen Prüfungen nur auf potenziell betroffene Objekte zu beschränken.

Verwenden Sie die Abfragen im Abschnitt Anhang C , um potenziell betroffene Tabellen zu identifizieren. Das Skript im Abschnitt Anhang D kann verwendet werden, um Auf der Grundlage der im Abschnitt Anhang C aufgeführten Abfragen zu generieren und CHECKCONSTRAINTS Einschränkungen zu erstellenCHECKTABLE.

DBCC CHECKCONSTRAINTS

Verwenden Sie das folgende Skript, um die Einschränkungen im Zusammenhang mit einer einzelnen Tabelle oder Ansicht zu überprüfen:

USE [database_name]

GO

DBCC TRACEON(139, -1)

GO

DBCC CHECKCONSTRAINTS()

GO

DBCC TRACEOFF(139, -1)

GO

Die Verwendung des Ablaufverfolgungskennzeichens stellt sicher, dass die Überprüfungen mithilfe der verbesserten Genauigkeits- und Konvertierungslogik durchgeführt werden, die sich in Kompatibilitätsebene 130 befindet, wodurch die verbesserte Semantik erzwungen wird, auch wenn die Datenbank über eine niedrigere Kompatibilitätsstufe verfügt.

Wenn die CHECKCONSTRAINTS Anweisung abgeschlossen ist und kein Resultset zurückgibt, ist keine zusätzliche Aktion erforderlich.

Wenn die Anweisung ein Resultset zurückgibt, gibt jede Zeile in den Ergebnissen eine Verletzung einer Einschränkung an und stellt auch die Werte bereit, die gegen die Einschränkung verstoßen.

Speichern Sie die Namen der Tabellen und Einschränkungen zusammen mit den Werten, die den Verletzten verursacht haben (die WHERE Spalte im Resultset).

DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS

Verwenden Sie das folgende Skript, um die dauerhaften Strukturen zu überprüfen, die sich auf eine einzelne Tabelle oder Ansicht beziehen:

USE [database_name]

GO

DBCC TRACEON(139, -1)

GO

DBCC CHECKTABLE() WITH EXTENDED_LOGICAL_CHECKS, NO_INFOMSGS, TABLERESULTS

GO

DBCC TRACEOFF(139, -1)

GO

Wenn die CHECKTABLE Anweisung erfolgreich abgeschlossen wird, ist keine zusätzliche Aktion erforderlich.

Wenn die Anweisung mit Fehlern abgeschlossen ist, führen Sie die folgenden Schritte aus:

  1. Speichern Sie die Ergebnisse aus der Ausführung der DBCC Anweisung, die im Nachrichtenbereich in SSMS gefunden wurde, in einer Datei.
  2. Stellen Sie sicher, dass alle gemeldeten Fehler mit dauerhaften Strukturen zusammenhängen, wie in Tabelle 1 aufgeführt.
  3. Nachdem Sie die Überprüfung auf Tabellenebene abgeschlossen haben, fahren Sie mit Schritt 3 fort.

Schritt 3: Upgrade auf Kompatibilitätsebene 130

Wenn die Kompatibilitätsebene der Datenbank bereits 130 ist, können Sie diesen Schritt überspringen.

Die Kompatibilitätsebene der Datenbank kann mithilfe des folgenden Skripts in 130 geändert werden:

USE [database_name]

GO

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=130

GO

Notiz

Da es Änderungen des Abfrageoptimierrs unter Kompatibilitätsebene 130 gibt, wird empfohlen, den Abfragespeicher zu aktivieren, bevor Sie die Kompatibilitätsstufe ändern. Weitere Informationen finden Sie im Abschnitt "Beibehalten der Leistungsstabilität während des Upgrades auf neuere SQL Server" in Abfragespeicher Verwendungsszenarien.

Schritt 4: Aktualisieren beibehaltener Strukturen

Wenn während der in Schritt 2 ausgeführten Überprüfung keine Inkonsistenzen gefunden wurden, sind Sie mit dem Upgrade fertig und können diesen Schritt überspringen. Wenn Inkonsistenzen in Schritt 2 gefunden wurden, sind zusätzliche Aktionen erforderlich, um die Inkonsistenzen aus der Datenbank zu entfernen. Die erforderlichen Aktionen hängen von der Art der betroffenen Struktur ab.

Wichtig

Führen Sie die Reparaturaktionen in diesem Schritt erst aus, nachdem die Datenbankkompatibilitätsebene in 130 geändert wurde.

Sichern der Datenbank (oder Datenbanken)

Es wird empfohlen, eine vollständige Datenbanksicherung durchzuführen, bevor Sie eine der im folgenden Abschnitt beschriebenen Aktionen ausführen. Wenn Sie Azure SQL-Datenbank verwenden, müssen Sie keine Sicherung selbst durchführen. Sie können die Point-in-Time-Wiederherstellungsfunktionalität immer verwenden, um in der Zeit zurückzukehren, falls bei einem der Updates ein Fehler auftritt.

CHECK-Einschränkungen

CHECK Das Korrigieren von Einschränkungsverletzungen erfordert eine Änderung der Daten in der Tabelle oder der CHECK Einschränkung selbst.

Aus dem Namen der Einschränkung (abgerufen in Schritt 2) können Sie die Einschränkungsdefinition wie folgt abrufen:

SELECT definition FROM sys.check_constraints

WHERE object_id= OBJECT_ID(N'constraint_name')

Um die betroffenen Tabellenzeilen zu prüfen, können Sie die Where-Informationen verwenden, die zuvor von der DBCC CHECKCONSTRAINTS Anweisung zurückgegeben wurden:

SELECT *

FROM [schema_name].[table_name]

WHERE Where_clause

Sie müssen die betroffenen Zeilen entweder aktualisieren oder die Einschränkungsdefinition ändern, um sicherzustellen, dass die Einschränkung nicht verletzt wird.

Aktualisieren von Tabellendaten

Es gibt keine harte Regel, die angibt, wie die Daten aktualisiert werden sollen. Im Allgemeinen führen Sie für jede von ihnen zurückgegebene DBCC CHECKCONSTRAINTSWhere-Anweisung die folgende Update-Anweisung aus:

UPDATE [schema_name].[table_name] SET new_column_values

WHERE Where_clause

Betrachten Sie die folgende Beispieltabelle mit einer Einschränkung und einer Zeile, die gegen die Einschränkung in Kompatibilitätsebene 130 verstößt:

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=120
GO
CREATE TABLE dbo.table1
(
c2 datetime,
c3 datetime,
c4 int,
CONSTRAINT chk1 CHECK (c4= (DATEDIFF (ms, c2, c3)))
)
GO
INSERT dbo.table1 (c2, c3, c4) VALUES
(convert(datetime, '1900-01-01 00:00:00.997'),
convert(datetime, '1900-01-01 00:00:01'), 3)
GO

In diesem Beispiel ist die Einschränkung einfach. Die Spalte c4 muss einem Ausdruck entsprechen, der beteiligt c2 ist und c3. Um die Tabelle zu aktualisieren, weisen Sie diesen Wert zu c4:

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=130
GO
UPDATE dbo.table1 SET c4 = datediff (ms, c2,c3)
WHERE [c2] = '1900-01-01 00:00:00.997' AND [c3] = '1900-01-01 00:00:01.000' AND [c4] = '3'
GO

Beachten Sie, dass die WHERE in der Update-Anweisung verwendete Klausel den where-Informationen entspricht, die von DBCC CHECKCONSTRAINTS.

Aktualisieren der CHECK-Einschränkung

Um eine CHECK Einschränkung zu ändern, müssen Sie sie ablegen und erneut erstellen. Es wird empfohlen, beide in derselben Transaktion auszuführen, falls probleme mit der aktualisierten Einschränkungsdefinition auftreten. Sie können die folgenden Transact-SQL-Daten verwenden:

BEGIN TRANSACTION

ALTER TABLE [schema_name].[table_name]

DROP CONSTRAINT [constraint_name]

ALTER TABLE [schema_name].[table_name]

ADD CONSTRAINT [constraint_name]

CHECK (new_constraint_definition)

COMMIT

GO

The following example updates the constraint chk1 in dbo.table1:

BEGIN TRANSACTION

ALTER TABLE dbo.table1

DROP CONSTRAINT chk1

ALTER TABLE dbo.table1

ADD CONSTRAINT chk1

CHECK (c4 <= DATEDIFF (ms, c2, c3))

COMMIT

GO

Gespeicherte berechnete Spalten

Die einfachste Möglichkeit zum Aktualisieren beibehaltener berechneter Spalten besteht darin, eine der Spalten zu aktualisieren, auf die von der berechneten Spalte verwiesen wird. Der neue Wert für die Spalte kann mit dem alten Wert identisch sein, sodass der Vorgang keine Benutzerdaten ändert.

Führen Sie diese Schritte für alle object_id im Zusammenhang mit Inkonsistenzen in berechneten Spalten aus, die Sie in Schritt 2 angegeben haben.

  1. Ermitteln berechneter Spalten:

    • Führen Sie die folgende Abfrage aus, um den Tabellennamen und die Namen der gespeicherten berechneten Spalten für die notierte abzurufen object_id:

      SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(t.name) AS 'table',
      QUOTENAME(c1.name) AS 'persisted computed column',
      c1.column_id AS 'computed_column_id' ,
      definition AS 'computed_column_definition'
      FROM sys.tables t
      JOIN sys.computed_columns c1 ON t.object_id=c1.object_id
      AND c1.is_persisted=1
      JOIN sys.schemas s ON t.schema_id=s.schema_id
      WHERE t.object_id=object_id
      
  2. Identifizieren von Spalten, auf die verwiesen wird:

  • Führen Sie die folgende Abfrage aus, um Spalten zu identifizieren, auf die von der berechneten Spalte verwiesen wird. Notieren Sie sich einen der Spaltennamen, auf die verwiesen wird:

    SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(o.name) AS 'referencing object',
    o.type_desc AS 'object type', referenced_minor_id AS 'referenced_column_id', c.name AS 'referenced_column_name'
    FROM sys.sql_expression_dependencies sed
    JOIN sys.computed_columns c1 ON sed.referencing_id=c1.object_id AND sed.referencing_minor_id=c1.column_id
    JOIN sys.objects o ON sed.referencing_id=o.object_id
    JOIN sys.schemas s ON o.schema_id=s.schema_id
    JOIN sys.columns c ON o.object_id=c.object_id AND sed.referenced_minor_id=c.column_id
    WHERE referencing_class=1 AND referenced_class=1 AND referencing_id=object_id AND referencing_minor_id=computed_column_id
    
  1. Führen Sie eine UPDATE Anweisung aus, die eine der referenzierten Spalten umfasst, um eine Aktualisierung der berechneten Spalte auszulösen:

    • Die folgende Anweisung löst eine Aktualisierung der Spalte aus, auf die von der berechneten Spalte verwiesen wird, und löst außerdem eine Aktualisierung der berechneten Spalte aus.

      UPDATE [schema_name].[table_name]
      SET referenced_column_name=ISNULL(referenced_column_name, referenced_column_name)
      
    • Der ISNULL Ausdruck in der Anweisung wird so gestaltet, dass der Wert der ursprünglichen Spalte nicht geändert wird, während gleichzeitig sichergestellt wird, dass die berechnete Spalte mithilfe der Auswertungslogik der DB-Kompatibilitätsebene 130 aktualisiert wird.

    • Beachten Sie, dass Sie bei sehr großen Tabellen möglicherweise nicht alle Zeilen in einer einzelnen Transaktion aktualisieren möchten. In einem solchen Fall können Sie die Aktualisierung in Batches ausführen, indem Sie der Update-Anweisung eine WHERE Klausel hinzufügen, die einen Zeilenbereich identifiziert, z. B. basierend auf dem Primärschlüssel.

  2. Identifizieren Sie Indizes, die auf die berechnete Spalte verweisen.

    SELECT i.name AS [index name]
    FROM sys.index_columns ic JOIN sys.indexes i ON ic.object_id=i.object_id AND ic.index_id=i.index_id
    WHERE i.object_id=object_id AND ic.column_id=computed_column_id
    

Diese Abfrage identifiziert alle Indizes, die auf die gespeicherte berechnete Spalte verweisen. Ein solcher Index muss neu erstellt werden. Führen Sie dazu die Schritte im folgenden Abschnitt aus.

Indizes, gefilterte Indizes und indizierte Ansichten

Inkonsistenzen in Indizes entsprechen Fehlern 8951 und 8952 (für Tabellen) oder 8907 und 8908 (für Ansichten) in der DBCC CHECK Ausgabe von Schritt 2.

Führen Sie zum DBCC CHECKTABLE Reparieren dieser Inkonsistenzen mit REPAIR_REBUILD. Dadurch werden die Indizes ohne Datenverlust repariert. Die Datenbank muss sich jedoch im Einzelbenutzermodus befinden und ist daher für andere Benutzer nicht verfügbar, während die Reparatur erfolgt.

Sie können auch betroffene Indizes manuell neu erstellen. Diese Option sollte verwendet werden, wenn die Workload nicht offline geschaltet werden kann, da die Indexneuerstellung als ONLINE-Vorgang (in unterstützten Editionen von SQL Server) ausgeführt werden kann.

Neuerstellen von Indizes

Wenn das Festlegen der Datenbank im Einzelbenutzermodus keine Option ist, können Sie Indizes einzeln neu erstellen, indem ALTER INDEX REBUILDSie für jeden in Schritt 2 identifizierten Index verwenden.

Verwenden Sie die folgende Abfrage, um die Tabellen- und Indexnamen für eine bestimmte object_id und index_id.

SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + N'.' + QUOTENAME(o.name) AS 'table', i.name AS 'index_name'

FROM sys.objects o JOIN sys.indexes i ON o.object_id=i.object_id

WHERE o.object_id = object_id AND i.index_id = index_id

Verwenden Sie die folgende Anweisung, um den Index neu zu erstellen:

ALTER INDEX index_name ON [schema_name].[table_name] REBUILD WITH (ONLINE=ON)

Notiz

Wenn Sie Standard-, Web- oder Express-Editionen verwenden, wird der Onlineindexbuild nicht unterstützt. Daher muss die Option WITH (ONLINE=ON) aus der ALTER INDEX Anweisung entfernt werden.

Das folgende Beispiel zeigt die Neuerstellung eines gefilterten Indexes:

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=120
GO
CREATE TABLE dbo.table2
(
    c2 datetime,
    c3 float
)
GO
INSERT dbo.table2 (c2,c3) VALUES ('1899-12-31 23:58:00.470', -0.00138344907407406)
GO
CREATE INDEX ix_1 ON dbo.table2(c2)
WHERE (c2=-0.00138344907407406)
GO
ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=130GOALTER INDEX ix_1 ON [dbo].[table2] REBUILD WITH (ONLINE=ON)
GO

Wenn Sie über regelmäßige Wartungspläne verfügen, empfehlen wir, diesen Index als Teil Der geplanten Wartung einzubeziehen.

Reparieren mithilfe von DBCC

Führen Sie für jedes (object_id) im Zusammenhang mit einem Index mit Inkonsistenzen aus, die Sie in Schritt 2 angegeben haben, das folgende Skript, um die Reparatur auszuführen. Dieses Skript legt die Datenbank im Einzelbenutzermodus für den Reparaturvorgang fest. Im schlimmsten Fall führt die Reparatur eine vollständige Indexneuerstellung durch.

USE [database_name]

GO

ALTER DATABASE CURRENT SET SINGLE_USER WITH ROLLBACK IMMEDIATE

GO

DBCC CHECKTABLE (object_id, REPAIR_REBUILD) WITH EXTENDED_LOGICAL_CHECKS, NO_INFOMSGS, TABLERESULTS

GO

ALTER DATABASE CURRENT SET MULTI_USER

GO

Anhang C: Abfragen zur Identifizierung von Kandidatentabellen

Die folgenden Skripts identifizieren Kandidatentabellen, die Sie anhand der Existenz beibehaltener Strukturen und Einschränkungen überprüfen möchten DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS, die von den Verbesserungen der Kompatibilitätsebene 130 betroffener Datentypen betroffen sind.

Die folgenden Abfragelistendetails zu den Tabellen und potenziell betroffenen Strukturen, die eine zusätzliche Überprüfung erfordern.

Indizierte Sichten

Die folgende Abfrage gibt alle indizierten Ansichten zurück, die auf Spalten verweisen, indem betroffene Datentypen oder eine der betroffenen integrierten Funktionen verwendet wird:

SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + N'.' + QUOTENAME(o.name) AS 'view', QUOTENAME(i.name) AS 'index',QUOTENAME(sed.referenced_schema_name) + N'.' + QUOTENAME(sed.referenced_entity_name) AS 'referenced table', QUOTENAME(c.name) AS 'referenced column', t.name AS 'data type',

-- if the data type is numeric, integer, or money, the only cases that warrent additional checks

-- with DBCC is if the view definition contains a float or datetime value, or a conversion to such value

s.definition

FROM sys.sql_expression_dependencies sed

JOIN sys.objects o ON sed.referencing_id = o.object_id AND o.type=N'V'

JOIN sys.indexes i ON o.object_id=i.object_id

JOIN sys.sql_modules s ON s.object_id=o.object_id

JOIN sys.columns c ON sed.referenced_id=c.object_id AND sed.referenced_minor_id=c.column_idJOIN sys.types t ON c.system_type_id=t.system_type_id

WHERE referencing_class=1 AND referenced_class=1 AND (c.system_type_id IN

( 59 --real

, 62 --float

, 58 --smalldatetime

, 61 --datetime

, 60 --money

, 122 --smallmoney

, 106 --decimal

, 108 --numeric

, 56 --int

, 48 --tinyint

, 52 -- smallint

, 41 --time

, 127 --bigint

) OR s.[definition] LIKE '%DATEDIFF%'

OR s.[definition] LIKE '%CONVERT%'

OR s.[definition] LIKE '%CAST%'

OR s.[definition] LIKE '%DATEPART%'

OR s.[definition] LIKE '%DEGREES%')

Gespeicherte berechnete Spalten

Die folgende Abfrage gibt alle Tabellen mit berechneten Spalten zurück, die auf andere Spalten verweisen, indem sie betroffene Datentypen verwenden oder eine der betroffenen integrierten Funktionen verwenden, wobei entweder die Spalte beibehalten oder aus einem Index verwiesen wird.

SELECT QUOTENAME(sed.referenced_schema_name) + N'.' +

QUOTENAME(sed.referenced_entity_name) AS 'candidate table with computed column',

QUOTENAME(c1.name) AS 'computed column', c1.is_persisted,QUOTENAME(c2.name) AS 'referenced column', t.name AS 'data type',

-- if the data type is numeric, integer, or money, the only cases that warrent additional checks

-- with DBCC is if the column definition contains a float or datetime value, or a conversion to such value

c1.definition

FROM sys.sql_expression_dependencies sed

JOIN sys.computed_columns c1 ON sed.referencing_id=c1.object_id AND sed.referencing_minor_id=c1.column_id

JOIN sys.columns c2 ON sed.referenced_id=c2.object_id AND sed.referenced_minor_id=c2.column_id

JOIN sys.types t ON c2.system_type_id=t.system_type_idWHERE referencing_class=1 AND referenced_class=1

AND (c2.system_type_id IN

( 59 --real

, 62 --float

, 58 --smalldatetime

, 61 --datetime

, 60 --money

, 122 --smallmoney

, 106 --decimal

, 108 --numeric

, 56 --int

, 48 --tinyint

, 52 -- smallint

, 41 --time

, 127 --bigint

) OR c1.[definition] LIKE '%DATEDIFF%'

OR c1.[definition] LIKE '%CONVERT%'

OR c1.[definition] LIKE '%DATEPART%'

OR c1.[definition] LIKE '%DEGREES%')

AND (

-- the column is persisted

c1.is_persisted=1

-- OR the column is included in an index

OR EXISTS (SELECT 1 FROM sys.index_columns ic WHERE ic.object_id=c1.object_id AND ic.column_id=c1.column_id)

)

Gefilterte Indizes

Die folgende Abfrage gibt alle Tabellen mit gefilterten Indizes zurück, die auf Spalten in der Filterbedingung verweisen, die betroffene Datentypen aufweisen:

SELECT QUOTENAME(sed.referenced_schema_name) + N'.' +

QUOTENAME(sed.referenced_entity_name) AS 'candidate table with filtered index',

QUOTENAME(i.name) AS 'referencing index',

QUOTENAME(c.name) AS 'referenced column',

t.name AS 'data type',

-- if the data type is numeric, integer, or money, the only cases that warrent additional checks

-- with DBCC is where the filter condition contains a float or datetime value

i.filter_definition AS 'filter condition'

FROM sys.sql_expression_dependencies sed

JOIN sys.indexes i ON sed.referencing_id=i.object_id AND sed.referencing_minor_id=i.index_id

JOIN sys.columns c ON sed.referenced_id=c.object_id AND sed.referenced_minor_id=c.column_id

JOIN sys.types t ON c.system_type_id=t.system_type_id

WHERE referencing_class=7 AND referenced_class=1 AND i.has_filter=1

AND c.system_type_id IN ( 59 --real

, 62 --float

, 58 --smalldatetime

, 61 --datetime

, 60 --money

, 122 --smallmoney

, 106 --decimal

, 108 --numeric

, 56 --int

, 48 --tinyint

, 52 -- smallint

, 41 --time

, 127 --bigint

)

Check-Einschränkungen

Die folgende Abfrage listet alle Tabellen mit Prüfeinschränkungen auf, die auf betroffene Datentypen oder integrierte Funktionen verweisen:

SELECT QUOTENAME(sed.referenced_schema_name) + N'.' +

QUOTENAME(sed.referenced_entity_name) AS 'candidate table with check constraint',

QUOTENAME(c.name) AS 'constraint_name', c.definition AS 'constraint_definition',

QUOTENAME(col.name) AS 'referenced column', t.name AS 'data type'

FROM sys.sql_expression_dependencies sed

JOIN sys.check_constraints c ON sed.referencing_id=c.object_id AND sed.referencing_class=1

JOIN sys.columns col ON sed.referenced_id=col.object_id AND sed.referenced_minor_id=col.column_id

JOIN sys.types t ON col.system_type_id=t.system_type_id

WHERE referencing_class=1 AND referenced_class=1 AND (col.system_type_id IN

( 59 --real

, 62 --float

, 58 --smalldatetime

, 61 --datetime

, 60 --money

, 122 --smallmoney

, 106 --decimal

, 108 --numeric

, 56 --int

, 48 --tinyint

, 52 -- smallint

, 41 --time

, 127 --bigint)

OR c.[definition] LIKE '%DATEDIFF%'

OR c.[definition] LIKE '%CONVERT%'

OR c.[definition] LIKE '%DATEPART%'

OR c.[definition] LIKE '%DEGREES%')

Anhang D: Skript zum Erstellen von CHECK*-Anweisungen

Das folgende Skript kombiniert die Abfragen aus dem vorherigen Anhang und vereinfacht die Ergebnisse, indem eine Liste von Tabellen und Ansichten in Form von CHECKCONSTRAINTS und CHECKTABLE Anweisungen dargestellt wird.

DECLARE @CRLF nvarchar(10) = CHAR(13) + CHAR(10);
DECLARE @sql nvarchar(max) = N'DBCC TRACEON(139,-1); ' + @CRLF ;

SELECT @sql += N'DBCC CHECKTABLE (N''' + object_for_checktable + N''') WITH EXTENDED_LOGICAL_CHECKS, NO_INFOMSGS, TABLERESULTS; ' + @CRLF
FROM
(

--indexed views
SELECT DISTINCT QUOTENAME(SCHEMA_NAME(o.schema_id)) + N'.' + QUOTENAME(o.name) AS 'object_for_checktable'
FROM sys.sql_expression_dependencies AS sed
 INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id AND o.type = N'V'
 INNER JOIN sys.indexes AS i ON o.object_id = i.object_id
 INNER JOIN sys.sql_modules AS s ON s.object_id = o.object_id
 INNER JOIN sys.columns AS c ON sed.referenced_id = c.object_id AND sed.referenced_minor_id = c.column_id
 INNER JOIN sys.types AS t ON c.system_type_id = t.system_type_id

WHERE referencing_class = 1 AND referenced_class=1 
 AND (c.system_type_id IN 
( 59 --real
 , 62 --float
 , 58 --smalldatetime
 , 61 --datetime
 , 60 --money
 , 122 --smallmoney
 , 106 --decimal
 , 108 --numeric
 , 56 --int
 , 48 --tinyint
 , 52 -- smallint
 , 41 --time
 , 127 --bigint
) OR s.[definition] LIKE N'%DATEDIFF%'
 OR s.[definition] LIKE N'%CONVERT%'
 OR s.[definition] LIKE N'%CAST%'
 OR s.[definition] LIKE N'%DATEPART%'
 OR s.[definition] LIKE N'%DEGREES%')

UNION

--persisted computed columns
SELECT DISTINCT QUOTENAME(sed.referenced_schema_name) + N'.' + QUOTENAME(sed.referenced_entity_name) AS 'object_for_checktable'
FROM sys.sql_expression_dependencies AS sed
INNER JOIN sys.computed_columns AS c1 ON sed.referencing_id = c1.object_id AND sed.referencing_minor_id = c1.column_id
INNER JOIN sys.columns AS c2 ON sed.referenced_id=c2.object_id AND sed.referenced_minor_id = c2.column_id
INNER JOIN sys.types AS t ON c2.system_type_id = t.system_type_id
WHERE referencing_class = 1 AND referenced_class = 1 
 AND (c2.system_type_id IN
( 59 --real
 , 62 --float
 , 58 --smalldatetime
 , 61 --datetime
 , 60 --money
 , 122 --smallmoney
 , 106 --decimal
 , 108 --numeric
 , 56 --int
 , 48 --tinyint
 , 52 -- smallint
 , 41 --time
 , 127 --bigint
) OR c1.[definition] LIKE N'%DATEDIFF%'
 OR c1.[definition] LIKE N'%CONVERT%'
 OR c1.[definition] LIKE N'%DATEPART%'
 OR c1.[definition] LIKE N'%DEGREES%')
AND (
-- the column is persisted
c1.is_persisted = 1 
-- OR the column is included in an index
OR EXISTS (SELECT 1 FROM sys.index_columns AS ic 
WHERE ic.object_id = c1.object_id AND ic.column_id=c1.column_id)
)

UNION

--indexed views
SELECT DISTINCT QUOTENAME(sed.referenced_schema_name) + N'.' + QUOTENAME(sed.referenced_entity_name) AS 'object_for_checktable'
FROM sys.sql_expression_dependencies AS sed 
INNER JOIN sys.indexes AS i ON sed.referencing_id = i.object_id AND sed.referencing_minor_id = i.index_id
INNER JOIN sys.columns AS c ON sed.referenced_id = c.object_id AND sed.referenced_minor_id = c.column_id 
INNER JOIN sys.types AS t ON c.system_type_id = t.system_type_id
WHERE referencing_class = 7 AND referenced_class = 1 AND i.has_filter = 1
AND c.system_type_id IN ( 
 59 --real
 , 62 --float
 , 58 --smalldatetime
 , 61 --datetime
 , 60 --money
 , 122 --smallmoney
 , 106 --decimal
 , 108 --numeric
 , 56 --int
 , 48 --tinyint
 , 52 -- smallint
 , 41 --time
 , 127 --bigint
)) AS a

SELECT @sql += N'DBCC CHECKCONSTRAINTS (N''' + object_for_checkconstraints + N'''); ' + @CRLF
FROM
(

SELECT DISTINCT QUOTENAME(sed.referenced_schema_name) + N'.' + QUOTENAME(sed.referenced_entity_name) AS 'object_for_checkconstraints'
FROM sys.sql_expression_dependencies AS sed 
INNER JOIN sys.check_constraints AS c ON sed.referencing_id = c.object_id AND sed.referencing_class = 1
INNER JOIN sys.columns AS col ON sed.referenced_id = col.object_id AND sed.referenced_minor_id = col.column_id
INNER JOIN sys.types AS t ON col.system_type_id = t.system_type_id
WHERE referencing_class = 1 AND referenced_class = 1 AND (col.system_type_id IN 
( 59 --real
 , 62 --float
 , 58 --smalldatetime
 , 61 --datetime
 , 60 --money
 , 122 --smallmoney
 , 106 --decimal
 , 108 --numeric
 , 56 --int
 , 48 --tinyint
 , 52 -- smallint
 , 41 --time
 , 127 --bigint
) OR c.[definition] LIKE N'%DATEDIFF%'
 OR c.[definition] LIKE N'%CONVERT%'
 OR c.[definition] LIKE N'%DATEPART%'
 OR c.[definition] LIKE N'%DEGREES%')
) a

SET @sql += N'DBCC TRACEOFF(139,-1);';

PRINT @sql;

--to run the script immediately, use the following command:
--EXECUTE sp_executesql @sql;
GO