Delen via


Verbeteringen in SQL Server en Azure SQL Database bij het verwerken van bepaalde gegevenstypen en ongebruikelijke bewerkingen

In dit artikel wordt beschreven hoe persistente structuren in uw SQL Server-database kunnen worden gevalideerd als onderdeel van het compatibiliteitsniveau van de upgrade en hoe eventuele betrokken structuren opnieuw kunnen worden opgebouwd nadat u het compatibiliteitsniveau hebt bijgewerkt.

Oorspronkelijke productversie: SQL Server 2017, SQL Server 2016
Oorspronkelijk KB-nummer: 4010261

De database-engine in Microsoft SQL Server 2016 en Azure SQL Database bevat verbeteringen in gegevenstypeconversies en verschillende andere bewerkingen. De meeste van deze verbeteringen bieden meer precisie wanneer u met typen drijvende komma en ook met klassieke datum/tijd-typen werkt.

Deze verbeteringen zijn allemaal beschikbaar wanneer u een databasecompatibiliteitsniveau van ten minste 130 gebruikt. Dit betekent dat u voor sommige (meestal ongebruikelijke) expressies verschillende resultaten kunt zien voor sommige invoerwaarden nadat u de database hebt bijgewerkt naar compatibiliteitsniveau 130 of hoger. Deze resultaten kunnen worden weerspiegeld in:

  • persistente structuren in de database
  • opgenomen tabelgegevens die onderhevig zijn aan CHECK beperkingen
  • persistente berekende kolommen
  • indexen die verwijzen naar berekende kolommen
  • gefilterde indexen en geïndexeerde weergaven.

Als u een database hebt die is gemaakt in een eerdere versie van SQL Server, raden we u aan extra validatie uit te voeren nadat u een upgrade hebt uitgevoerd naar SQL Server 2016 of hoger en voordat u het compatibiliteitsniveau van de database wijzigt.

Als u merkt dat een van de persistente structuren in uw database wordt beïnvloed door deze wijzigingen, raden we u aan de betrokken structuren opnieuw te bouwen nadat u het compatibiliteitsniveau van de database hebt bijgewerkt. Als u dit doet, profiteert u van deze verbeteringen in SQL Server 2016 of hoger.

In dit artikel wordt beschreven hoe persistente structuren in uw database kunnen worden gevalideerd als onderdeel van de upgrade naar compatibiliteitsniveau 130 of hoger en hoe betrokken structuren opnieuw kunnen worden opgebouwd nadat u het compatibiliteitsniveau hebt gewijzigd.

Validatiestappen tijdens een upgrade naar databasecompatibiliteitsniveau

Vanaf SQL Server 2016 bevatten zowel SQL Server als Azure SQL Database verbeteringen in de precisie van de volgende bewerkingen:

  • Ongebruikelijke conversies van gegevenstypen. Deze omvatten het volgende:
    • Float/integer naar/from datetime/smalldatetime
    • Real/float to/from numeriek/money/smallmoney
    • Zweven naar echt
  • Sommige gevallen van DATEPART/DATEDIFF en DEGREES
  • CONVERT die gebruikmaakt van een NULL stijl

Als u deze verbeteringen wilt gebruiken voor de evaluatie van expressies in uw toepassing, wijzigt u het compatibiliteitsniveau van uw databases in 130 (voor SQL Server 2016) of 140 (voor SQL Server 2017 en Azure SQL Database). Zie de sectie Bijlage A voor meer informatie over alle wijzigingen en enkele voorbeelden die de wijzigingen weergeven.

De volgende structuren in de database kunnen de resultaten van een expressie behouden:

  • Tabelgegevens die onderhevig zijn aan CHECK beperkingen
  • Persistente berekende kolommen
  • Indexen die gebruikmaken van berekende kolommen in de sleutel of opgenomen kolommen
  • Gefilterde indexen
  • Geïndexeerde weergaven

Bekijk het volgende scenario:

  • U hebt een database die is gemaakt met een eerdere versie van SQL Server of die al is gemaakt in SQL Server 2016 of een latere versie, maar op compatibiliteitsniveau 120 of een lager niveau.

  • U gebruikt expressies waarvan de precisie is verbeterd als onderdeel van de definitie van persistente structuren in uw database.

In dit scenario hebt u mogelijk permanente structuren die worden beïnvloed door de verbeteringen in precisie die worden geïmplementeerd met behulp van compatibiliteitsniveau 130 of hoger. Als dit het geval is, raden we u aan de persistente structuren te valideren en een structuur te herbouwen die wordt beïnvloed.

Als u structuren hebt beïnvloed en u deze niet opnieuw opbouwt nadat u het compatibiliteitsniveau hebt gewijzigd, kunnen er iets andere queryresultaten optreden. De resultaten zijn afhankelijk van of een bepaalde index, berekende kolom of weergave wordt gebruikt en of gegevens in een tabel kunnen worden beschouwd als een schending van een beperking.

Notitie

Traceringsvlag 139 in SQL Server

De globale traceringsvlag 139 wordt geïntroduceerd in SQL Server 2016 CU3 en Service Pack (SP) 1 om juiste conversiesemantiek af te dwingen in het bereik van DBCC-controleopdrachten zoals DBCC CHECKDB, DBCC CHECKTABLEen DBCC CHECKCONSTRAINTS wanneer u de verbeterde precisie- en conversielogica analyseert die is geïntroduceerd met compatibiliteitsniveau 130 op een database met een eerder compatibiliteitsniveau.

Waarschuwing

Traceringsvlag 139 is niet bedoeld om continu in een productieomgeving te worden ingeschakeld en moet worden gebruikt voor het uitvoeren van de databasevalidatiecontroles die in dit artikel worden beschreven. Daarom moet deze worden uitgeschakeld met behulp van dbcc traceoff (139, -1) dezelfde sessie, nadat de validatiecontroles zijn voltooid.

Traceringsvlag 139 wordt ondersteund vanaf SQL Server 2016 CU3 en SQL Server 2016 SP1.

Voer de volgende stappen uit om het compatibiliteitsniveau te upgraden:

  1. Voer de validatie uit om eventuele betrokken persistente structuren te identificeren:
    1. Schakel traceringsvlag 139 in door uit te voeren DBCC TRACEON(139, -1).
    2. Uitvoeren DBCC CHECKDB/TABLE en CHECKCONSTRAINTS opdrachten.
    3. Schakel traceringsvlag 139 uit door uit te voeren DBCC TRACEOFF(139, -1).
  2. Wijzig het databasecompatibiliteitsniveau in 130 (voor SQL Server 2016) of 140 (voor SQL Server 2017 en Azure SQL Database).
  3. Bouw alle structuren die u hebt geïdentificeerd in stap 1.

Notitie

Traceringsvlagmen in Azure SQL Database Setting-traceringsvlagmen worden niet ondersteund in Azure SQL Database. Daarom moet u het compatibiliteitsniveau wijzigen voordat u validatie uitvoert:

  1. Upgrade het compatibiliteitsniveau van de database naar 140.
  2. Valideer om eventuele betrokken persistente structuren te identificeren.
  3. Bouw de structuren opnieuw die u in stap 2 hebt geïdentificeerd.
  • Bijlage A bevat een gedetailleerde lijst met alle precisieverbeteringen en geeft een voorbeeld voor elk.

  • Bijlage B bevat een gedetailleerd stapsgewijze procedure om validatie uit te voeren en eventuele betrokken structuren opnieuw te bouwen.

  • Bijlage C en Bijlage D bevatten scripts om mogelijk beïnvloede objecten in de database vast te stellen. Daarom kunt u uw validaties instellen en bijbehorende scripts genereren om de controles uit te voeren. Als u het gemakkelijkst wilt bepalen of persistente structuren in uw databases worden beïnvloed door de precisieverbeteringen in compatibiliteitsniveau 130, voert u het script uit in bijlage D om de juiste validatiecontroles te genereren en voert u dit script uit om validatie uit te voeren.

Bijlage A: wijzigingen in compatibiliteitsniveau 130

Deze bijlage bevat gedetailleerde lijsten met de verbeteringen in de evaluatie van expressies in compatibiliteitsniveau 130. Elke wijziging bevat een bijbehorende voorbeeldquery. De query's kunnen worden gebruikt om de verschillen weer te geven tussen het uitvoeren in een database die gebruikmaakt van een compatibiliteitsniveau vóór 130 in vergelijking met een database die gebruikmaakt van compatibiliteitsniveau 130.

De volgende tabellen bevatten conversies van gegevenstypen en aanvullende bewerkingen.

Conversies van gegevenstypen

Van Tot Wijzigen Voorbeeldquery Resultaat voor compatibiliteitsniveau < 130 Resultaat voor compatibiliteitsniveau = 130
float, , realnumeric, , decimal, of moneysmallmoney datetime of smalldatetime Verhoog de afrondingsprecisie. Voorheen werden dag en tijd afzonderlijk geconverteerd en werden de resultaten afgekapt voordat u ze combineerde. DECLARE @f FLOAT = 1.2 DECLARE @d DATETIME = @f SELECT CAST(@d AS FLOAT) 1.19999996141975 1.2
datetime bigint, int, or smallint Een negatieve datum/tijd waarvan het tijdgedeelte precies een halve dag is of in een tik van een halve dag onjuist wordt afgerond (het resultaat is uitgeschakeld door 1). DECLARE @h DATETIME = -0.5 SELECT @h, CAST(@h AS INT) 0 -1
datetime of smalldatetime float, real, numeric, money, or smallmoney Verbeterde precisie voor de laatste 8 bits precisie in sommige gevallen. 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 Grenscontroles zijn minder streng. SELECT CAST (3.40282347000E+038 AS REAL) Rekenkundige overloop 3.402823E+38
numeric, money en smallmoney float Wanneer de invoerschaal nul is, is er een afrondingsimplicatie wanneer u de vier delen van numerieke waarden combineert. DECLARE @n NUMERIC(38, 0)= 41538374868278625639929991208632320 DECLARE @f FLOAT = CAST(@n AS FLOAT) SELECT CONVERT(BINARY(8), @f) 0x4720000000000000 0x4720000000000001
numeric, money en smallmoney float Wanneer de invoerschaal niet nul is, is er een afrondingsfout wanneer u deelt door 10^schaal. DECLARE @n NUMERIC(18, 10) = 12345678.0123456781 DECLARE @f FLOAT = CAST(@n AS FLOAT) SELECT CAST(@f AS BINARY(8)) 0x41678C29C06522C4 0x41678C29C06522C3
real of float numeriek Verbeterde afrondingsprecisie in sommige gevallen. DECLARE @f float = 0.14999999999999999 SELECT CAST(@f AS numeric(1, 1)) 0,2 0,1
real of float numeriek Verbeterde precisie wanneer u in sommige gevallen naar meer dan 16 cijfers rondt. DECLARE @v decimal(38, 18) = 1E-18 SELECT @v 0.000000000000000000 0.000000000000000001
real of float money of smallmoney Verbeterde nauwkeurigheid wanneer u in sommige gevallen grote getallen converteert. DECLARE @f float = 2SET @f = POWER(@f, 49) + POWER(@f, -2) SELECT CAST(@f AS money) 562949953421312.2048 562949953421312.25
(n)(var)char numeric Een invoer van meer dan 39 tekens activeert niet langer noodzakelijkerwijs een rekenkundige overloop. DECLARE @value nchar(100) = '1.11111111111111111111111111111111111111' SELECT CAST(@value AS decimal(2,1)) Rekenkundige overloop 1.1
(n)(var)char bit Ondersteunt voorloopspaties en borden. DECLARE @value nvarchar(100) = '1' SELECT CAST(@value AS bit) De conversie is mislukt bij het converteren van de nvarchar waarde '1' naar een gegevenstype-bit. 1
datetime time of datetime2 Verbeterde precisie wanneer u converteert naar datum-/tijdtypen met een hogere precisie. Houd er rekening mee dat datum/tijd-waarden worden opgeslagen als tikken die 1/300e van een seconde vertegenwoordigen. In de nieuwere typen tijd en datum/tijd2 wordt een discreet aantal cijfers opgeslagen, waarbij het aantal cijfers overeenkomt met de precisie. 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 of datetime2 datetime Verbeterde afronding in sommige gevallen. 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

Bewerking

Bewerking Wijzigen Voorbeeldquery Resultaat voor compatibiliteitsniveau <130 Resultaat voor compatibiliteitsniveau 130
Gebruik de RADIANS of DEGREES ingebouwde functie die gebruikmaakt van het numerieke gegevenstype. DEGREES deelt door pi/180, waarbij het eerder vermenigvuldigd werd met 180/pi. Vergelijkbaar met RADIANS. DECLARE @arg1 numeric = 1 SELECT DEGREES(@arg1) 57.295779513082323000 57.295779513082322865
Numerieke opteling of aftrekking wanneer de schaal van één operand groter is dan de schaal van het resultaat. Afronding vindt altijd plaats na het optellen of aftrekken, terwijl het eerder soms voor kon komen. DECLARE @p1 numeric(38, 2) = -1.15 DECLARE @p2 numeric(38, 1) = 10 SELECT @p1 + @p2 8.8 8.9
CONVERT met NULL stijl. CONVERT met NULL stijl wordt altijd geretourneerd NULL wanneer het doeltype numeriek is. SELECT CONVERT (SMALLINT, '0', NULL); 0 NULL
DATEPART die gebruikmaakt van de optie microseconden of nanoseconden, met het gegevenstype datum/tijd. De waarde wordt niet meer afgekapt op milliseconden voordat deze wordt geconverteerd naar micro- of nanoseconden. DECLARE @dt DATETIME = '01-01-1900 00:00:00.003'; SELECT DATEPART(MICROSECOND, @dt); 3000 3333
DATEDIFF die gebruikmaakt van de optie microseconden of nanoseconden, met het gegevenstype datum/tijd. De waarde wordt niet meer afgekapt op milliseconden voordat deze wordt geconverteerd naar micro- of nanoseconden. 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 3333
Vergelijking tussen datum/tijd- en datum/tijd2-waarden met niet-nulwaarden voor milliseconden. De datum/tijd-waarde wordt niet meer afgekapt op milliseconden wanneer u een vergelijking met een datum/tijd2-waarde uitvoert. Dit betekent dat bepaalde waarden die eerder gelijk waren vergeleken, niet langer gelijk zijn aan elkaar vergelijken. 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.0030000, 1900-01-01 00:00:00.003 gelijk aan 1900-01-01 00:00:00.003333, 1900-01-01 00:00:00.003 ongelijke
ROUND functie die gebruikmaakt van het float gegevenstype. Afrondingsresultaten verschillen. SELECT ROUND(CAST (-0.4175 AS FLOAT), 3) -0.418 -0.417

Bijlage B: Stappen voor het verifiëren en bijwerken van persistente structuren

U wordt aangeraden te bepalen of de database persistente structuren heeft die worden beïnvloed door de wijzigingen in compatibiliteitsniveau 130 en dat u eventuele betrokken structuren opnieuw bouwt.

Dit geldt alleen voor persistente structuren die zijn gemaakt in de database op een oudere versie van SQL Server of met behulp van een compatibiliteitsniveau dat lager is dan 130. De persistente structuren die mogelijk worden beïnvloed, zijn onder andere:

  • Tabelgegevens die onderhevig zijn aan CHECK beperkingen
  • Persistente berekende kolommen
  • Indexen die gebruikmaken van berekende kolommen in de sleutel of opgenomen kolommen
  • Gefilterde indexen
  • Geïndexeerde weergaven

Voer in deze situatie de volgende procedure uit.

Stap 1: Compatibiliteitsniveau van database controleren

  1. Controleer het compatibiliteitsniveau van uw database met behulp van de procedure die wordt beschreven in Weergeven of het compatibiliteitsniveau van een database wijzigen.
  2. Als het compatibiliteitsniveau van de database lager is dan 130, raden we u aan de validatie uit te voeren die wordt beschreven in stap 2 voordat u het compatibiliteitsniveau verhoogt tot 130.

Stap 2: Betrokken persistente structuren identificeren

Bepaal of de database persistente structuren bevat die worden beïnvloed door de verbeterde precisie- en conversielogica in compatibiliteitsniveau 130 op een van de volgende manieren:

  • DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS, waarmee alle structuren in de database worden gevalideerd.
  • DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS, waarmee de structuren met betrekking tot één tabel worden gevalideerd.

De optie WITH EXTENDED_LOGICAL_CHECKS is vereist om ervoor te zorgen dat de persistente waarden worden vergeleken met berekende waarden en om gevallen te markeren waarin er een verschil is. Omdat deze controles uitgebreid zijn, is de runtime van DBCC instructies die deze optie gebruiken langer dan actieve DBCC instructies zonder de optie. Daarom is de aanbeveling voor grote databases te gebruiken DBCC CHECKTABLE om afzonderlijke tabellen vast te stellen.

DBCC CHECKCONSTRAINTS kan worden gebruikt om beperkingen te valideren CHECK . Deze instructie kan worden gebruikt op database- of tabelniveau.

DBCC CHECK instructies moeten altijd worden uitgevoerd tijdens een onderhoudsvenster, vanwege de mogelijke impact van de controles op de onlineworkload.

Validatie op databaseniveau

Validatie op databaseniveau is geschikt voor kleine en middelgrote databases. Gebruik validatie op tabelniveau voor grote databases.

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS wordt gebruikt om alle persistente structuren in de database te valideren.

DBCC CHECKCONSTRAINTS wordt gebruikt om alle CHECK beperkingen in de database te valideren.

DBCC CHECKCONSTRAINTS wordt gebruikt om de integriteit van beperkingen te valideren. Gebruik het volgende script om de database te valideren:

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

Het gebruik van de traceringsvlag zorgt ervoor dat de controles worden uitgevoerd met behulp van de verbeterde precisie- en conversielogica in compatibiliteitsniveau 130, waardoor de juiste conversiesemantiek wordt afgedwongen, zelfs wanneer de database een lager compatibiliteitsniveau heeft.

Als de CHECKCONSTRAINTS instructie is voltooid en geen resultatenset retourneert, is er geen extra actie nodig.

Als de instructie een resultatenset retourneert, geeft elke regel in de resultaten een schending van een beperking aan en bevat deze ook de waarden die de beperking schenden.

  • Sla de namen van de tabellen en beperkingen op, samen met de waarden die de schending hebben veroorzaakt (de WHERE kolom in de resultatenset).

In het volgende voorbeeld ziet u een tabel met een CHECK beperking en één rij die voldoet aan de beperking onder lagere compatibiliteitsniveaus, maar die de beperking onder compatibiliteitsniveau 130 schendt.

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

De CHECKCONSTRAINT opdracht retourneert de volgende resultaten.

Tabel Beperking Waar
[dbo]. [tabel1] [chk1] [c2] = '1900-01-01 00:00:00.997' EN [c3] = '1900-01-01 00:00:01.000' EN [c4] = '3'

Dit resultaat geeft aan dat de beperking [chk1] wordt geschonden voor de combinatie van kolomwaarden in 'Waar'.

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS

DBCC CHECKDB WITH EXTENDED_LOGICAL_CHECKS valideert alle persistente structuren in de database. Dit is de handigste optie omdat met één instructie alle structuren in de database worden gevalideerd. Deze optie is echter niet geschikt voor grote databases vanwege de verwachte runtime van de instructie.

Gebruik het volgende script om de hele database te valideren:

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

Het gebruik van de traceringsvlag zorgt ervoor dat de controles worden uitgevoerd met behulp van de verbeterde precisie- en conversielogica in compatibiliteitsniveau 130, waardoor de juiste conversiesemantiek wordt afgedwongen, zelfs wanneer de database een lager compatibiliteitsniveau heeft.

Als de CHECKDB instructie is voltooid, is er geen extra actie nodig.

Als de instructie is voltooid met fouten, voert u de volgende stappen uit:

  1. Sla de resultaten van de uitvoering van de DBCC instructie op in het berichtenvenster in SQL Server Management Studio (SSMS) naar een bestand.
  2. Controleer of een van de gerapporteerde fouten betrekking heeft op persistente structuren

Tabel 1: Persistente structuren en bijbehorende foutberichten voor inconsistenties

Beïnvloed type structuur Waargenomen foutberichten Noteer
Persistente berekende kolommen Msg 2537, tabelfout op niveau 16: object-id <object_id> , index-id <index_id> , . De recordcontrole (geldige berekende kolom) is mislukt. De waarden zijn. object-id <object_id> en index-id <index_id>
Indexen die verwijzen naar berekende kolommen in de sleutel of opgenomen kolommen gefilterde indexen Tabelfout msg 8951: tabel '<table_name>' (id <object_id>). Gegevensrij heeft geen overeenkomende indexrij in de index '<index_name>' (id <index_id>) en/of msg 8952 Tabelfout: tabel '<table_name>' (id <table_name>). Indexrij in index '' (id <index_id>) komt niet overeen met een gegevensrij. Daarnaast kunnen er secundaire fouten 8955 en/of 8956 zijn. Dit bevat details over de exacte rijen die zijn beïnvloed. Deze kunnen worden genegeerd voor deze oefening. object-id <object_id> en index-id <index_id>
Geïndexeerde weergaven Msg 8908 De geïndexeerde weergave '<view_name>' (object-id <object_id>) bevat niet alle rijen die de weergavedefinitie produceert. En/of Msg 8907 De geïndexeerde weergave '<view_name>' (object-id <object_id>) bevat rijen die niet zijn geproduceerd door de weergavedefinitie. object-id <object_id>

Nadat u de validatie op databaseniveau hebt voltooid, gaat u naar stap 3.

Validatie op objectniveau

Voor grotere databases is het handig om structuren en beperkingen voor één tabel of één weergave tegelijk te valideren om de grootte van onderhoudsvensters te verminderen of om de uitgebreide logische controles alleen te beperken tot mogelijk beïnvloede objecten.

Gebruik de query's in de sectie Bijlage C om mogelijk betrokken tabellen te identificeren. Het script in de sectie Bijlage D kan worden gebruikt voor het genereren CHECKTABLE en CHECKCONSTRAINTS de beperkingen op basis van de query's die worden vermeld in de sectie Bijlage C .

DBCC CHECKCONSTRAINTS

Gebruik het volgende script om de beperkingen met betrekking tot één tabel of weergave te valideren:

USE [database_name]

GO

DBCC TRACEON(139, -1)

GO

DBCC CHECKCONSTRAINTS()

GO

DBCC TRACEOFF(139, -1)

GO

Het gebruik van de traceringsvlag zorgt ervoor dat de controles worden uitgevoerd met behulp van de verbeterde precisie- en conversielogica die zich in compatibiliteitsniveau 130 bevindt, waardoor de verbeterde semantiek wordt afgedwongen, zelfs wanneer de database een lager compatibiliteitsniveau heeft.

Als de CHECKCONSTRAINTS instructie is voltooid en geen resultatenset retourneert, is er geen extra actie nodig.

Als de instructie wel een resultatenset retourneert, geeft elke regel in de resultaten een schending van een beperking aan en geeft ook de waarden op die de beperking schenden.

Sla de namen van de tabellen en beperkingen op, samen met de waarden die de schending hebben veroorzaakt (de WHERE kolom in de resultatenset).

DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS

Gebruik het volgende script om de persistente structuren te valideren die betrekking hebben op één tabel of weergave:

USE [database_name]

GO

DBCC TRACEON(139, -1)

GO

DBCC CHECKTABLE() WITH EXTENDED_LOGICAL_CHECKS, NO_INFOMSGS, TABLERESULTS

GO

DBCC TRACEOFF(139, -1)

GO

Als de CHECKTABLE instructie is voltooid, is er geen extra actie nodig.

Als de instructie is voltooid met fouten, voert u de volgende stappen uit:

  1. Sla de resultaten op van de uitvoering van de DBCC instructie, gevonden in het berichtenvenster in SSMS, in een bestand.
  2. Controleer of een van de gerapporteerde fouten betrekking heeft op persistente structuren, zoals vermeld in tabel 1.
  3. Nadat u de validatie op tabelniveau hebt voltooid, gaat u verder met stap 3.

Stap 3: Upgraden naar compatibiliteitsniveau 130

Als het compatibiliteitsniveau van de database al 130 is, kunt u deze stap overslaan.

Het compatibiliteitsniveau van de database kan worden gewijzigd in 130 met behulp van het volgende script:

USE [database_name]

GO

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL=130

GO

Notitie

Omdat er wijzigingen in queryoptimalisatie zijn onder compatibiliteitsniveau 130, raden we u aan om het queryarchief in te schakelen voordat u het compatibiliteitsniveau wijzigt. Zie de sectie Prestatiestabiliteit behouden tijdens de upgrade naar nieuwere SQL Server-sectie in Query Store-gebruiksscenario's voor meer informatie.

Stap 4: Persistente structuren bijwerken

Als er geen inconsistenties zijn gevonden tijdens de validatie die in stap 2 is uitgevoerd, bent u klaar met de upgrade en kunt u deze stap overslaan. Als inconsistenties zijn gevonden in stap 2, zijn er aanvullende acties vereist om de inconsistenties uit de database te verwijderen. De vereiste acties zijn afhankelijk van het type structuur dat wordt beïnvloed.

Belangrijk

Voer de herstelacties in deze stap pas uit nadat het compatibiliteitsniveau van de database is gewijzigd in 130.

Een back-up maken van uw database (of databases)

U wordt aangeraden een volledige databaseback-up te maken voordat u een van de acties uitvoert die in de volgende sectie worden beschreven. Als u Azure SQL Database gebruikt, hoeft u zelf geen back-up te maken; u kunt altijd de functionaliteit voor herstel naar een bepaald tijdstip gebruiken om terug te gaan in het geval er iets misgaat met een van de updates.

CHECK-beperkingen

Voor het corrigeren van schendingen van CHECK beperkingen is het wijzigen van de gegevens in de tabel of de CHECK beperking zelf vereist.

Met de naam van de beperking (verkregen in stap 2) kunt u de definitie van de beperking als volgt verkrijgen:

SELECT definition FROM sys.check_constraints

WHERE object_id= OBJECT_ID(N'constraint_name')

Als u de betrokken tabelrijen wilt controleren, kunt u de where-informatie gebruiken die eerder is geretourneerd door de DBCC CHECKCONSTRAINTS instructie:

SELECT *

FROM [schema_name].[table_name]

WHERE Where_clause

U moet de betreffende rijen bijwerken of de definitie van de beperking wijzigen om ervoor te zorgen dat de beperking niet wordt geschonden.

Tabelgegevens bijwerken

Er is geen harde regel waarin wordt aangegeven hoe de gegevens moeten worden bijgewerkt. Over het algemeen voert u voor elke andere Where-instructie die wordt geretourneerd door DBCC CHECKCONSTRAINTSde volgende update-instructie uit:

UPDATE [schema_name].[table_name] SET new_column_values

WHERE Where_clause

Bekijk de volgende voorbeeldtabel met een beperking en een rij die de beperking in compatibiliteitsniveau 130 schendt:

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 dit voorbeeld is de beperking eenvoudig. De kolom c4 moet gelijk zijn aan een expressie die betrekking heeft op c2 en c3. Als u de tabel wilt bijwerken, wijst u deze waarde toe aan 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

U ziet dat de WHERE component die in de update-instructie wordt gebruikt, overeenkomt met de where-informatie die wordt geretourneerd door DBCC CHECKCONSTRAINTS.

Beperking CHECK bijwerken

Als u een CHECK beperking wilt wijzigen, moet u deze verwijderen en opnieuw maken. We raden u aan beide in dezelfde transactie uit te voeren, voor het geval er problemen zijn met de bijgewerkte beperkingsdefinitie. U kunt de volgende Transact-SQL gebruiken:

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

Persistente berekende kolommen

De eenvoudigste manier om permanente berekende kolommen bij te werken, is door een van de kolommen waarnaar wordt verwezen door de berekende kolom bij te werken. De nieuwe waarde voor de kolom kan hetzelfde zijn als de oude waarde, zodat de bewerking geen gebruikersgegevens wijzigt.

Volg deze stappen voor alle object_id gerelateerde inconsistenties in berekende kolommen die u in stap 2 hebt genoteerd.

  1. Berekende kolommen identificeren:

    • Voer de volgende query uit om de tabelnaam en de namen van persistente berekende kolommen voor de genoteerde object_idop te halen:

      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. Kolommen waarnaar wordt verwezen identificeren:

  • Voer de volgende query uit om kolommen te identificeren waarnaar wordt verwezen door de berekende kolom. Noteer een van de kolomnamen waarnaar wordt verwezen:

    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. Voer een UPDATE instructie uit met een van de kolommen waarnaar wordt verwezen om een update van de berekende kolom te activeren:

    • Met de volgende instructie wordt een update geactiveerd van de kolom waarnaar wordt verwezen door de berekende kolom en wordt ook een update van de berekende kolom geactiveerd.

      UPDATE [schema_name].[table_name]
      SET referenced_column_name=ISNULL(referenced_column_name, referenced_column_name)
      
    • De ISNULL expressie in de instructie wordt zodanig gemaakt dat de waarde van de oorspronkelijke kolom niet wordt gewijzigd, terwijl u er nog steeds voor zorgt dat de berekende kolom wordt bijgewerkt met de evaluatielogica van DB-compatibiliteitsniveau 130.

    • Houd er rekening mee dat u voor zeer grote tabellen mogelijk niet alle rijen in één transactie wilt bijwerken. In dat geval kunt u de update in batches uitvoeren door een WHERE component toe te voegen aan de update-instructie die een bereik van rijen identificeert, bijvoorbeeld op basis van de primaire sleutel.

  2. Identificeer indexen die verwijzen naar de berekende kolom.

    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
    

Deze query identificeert alle indexen die verwijzen naar de persistente berekende kolom. Een dergelijke index moet opnieuw worden opgebouwd. Volg hiervoor de stappen in de volgende sectie.

Indexen, gefilterde indexen en geïndexeerde weergaven

Inconsistenties in indexen komen overeen met fouten 8951 en 8952 (voor tabellen) of 8907 en 8908 (voor weergaven) in de DBCC CHECK uitvoer van stap 2.

Als u deze inconsistenties wilt herstellen, voert DBCC CHECKTABLE u uit met REPAIR_REBUILD. Hiermee worden de indexenstructuren hersteld zonder gegevensverlies. De database moet zich echter in de modus voor één gebruiker bevinden en is daarom niet beschikbaar voor andere gebruikers tijdens het herstellen.

U kunt ook handmatig de betreffende indexen opnieuw opbouwen. Deze optie moet worden gebruikt als de workload niet offline kan worden gehaald, omdat het opnieuw opbouwen van de index kan worden uitgevoerd als een ONLINE-bewerking (in ondersteunde edities van SQL Server).

Indexen opnieuw samenstellen

Als het instellen van de database in de modus voor één gebruiker geen optie is, kunt u indexen afzonderlijk herbouwen met behulp van ALTER INDEX REBUILD, voor elke index die in stap 2 is geïdentificeerd.

Gebruik de volgende query om de tabel- en indexnamen voor een bepaalde object_id en 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

Gebruik de volgende instructie om de index opnieuw te bouwen:

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

Notitie

Als u standard-, web- of Express-edities gebruikt, wordt het bouwen van online indexen niet ondersteund. Daarom moet de optie WITH (ONLINE=ON) worden verwijderd uit de ALTER INDEX instructie.

In het volgende voorbeeld ziet u het opnieuw samenstellen van een gefilterde index:

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

Als u regelmatig onderhoudsplannen hebt, raden we u aan deze index opnieuw op te nemen als onderdeel van uw gepland onderhoud.

Herstellen met DBCC

Voor elke (object_id) met betrekking tot een index met inconsistenties die u in stap 2 hebt genoteerd, voert u het volgende script uit om het herstel uit te voeren. Met dit script wordt de database ingesteld in de modus voor één gebruiker voor de herstelbewerking. In het ergste geval voert de reparatie een volledige index opnieuw op.

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

Bijlage C: Query's om kandidaattabellen te identificeren

De volgende scripts identificeren kandidaattabellen die u mogelijk wilt valideren met behulp van DBCC CHECKTABLE WITH EXTENDED_LOGICAL_CHECKS, op basis van het bestaan van persistente structuren en beperkingen die gebruikmaken van gegevenstypen die worden beïnvloed door de verbeteringen in compatibiliteitsniveau 130.

De volgende set query's bevat details over de tabellen en mogelijk beïnvloede structuren waarvoor extra validatie is vereist.

Geïndexeerde weergaven

De volgende query retourneert alle geïndexeerde weergaven die verwijzen naar kolommen met behulp van betrokken gegevenstypen of met behulp van een van de betrokken ingebouwde functies:

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%')

Persistente berekende kolommen

De volgende query retourneert alle tabellen met berekende kolommen die verwijzen naar andere kolommen met behulp van betrokken gegevenstypen of met behulp van een van de betrokken ingebouwde functies, waarbij de kolom wordt behouden of waarnaar wordt verwezen vanuit een index.

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)

)

Gefilterde indexen

De volgende query retourneert alle tabellen met gefilterde indexen die verwijzen naar kolommen in de filtervoorwaarde die van invloed zijn op gegevenstypen:

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

)

Beperkingen controleren

De volgende query bevat alle tabellen met controlebeperkingen die verwijzen naar betrokken gegevenstypen of ingebouwde functies:

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%')

Bijlage D: Script voor het maken van CHECK*-instructies

Het volgende script combineert de query's uit de vorige bijlage en vereenvoudigt de resultaten door een lijst met tabellen en weergaven te presenteren in de vorm van CHECKCONSTRAINTS en CHECKTABLE instructies.

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