MSSQLSERVER_2570

Van toepassing op:SQL Server

Details

Attribute Value
Productnaam SQL Server
Gebeurtenis-id 2570
Bron van gebeurtenis MSSQLSERVER
Onderdeel SQLEngine
Symbolische naam DBCC_COLUMN_VALUE_OUT_OF_RANGE
Berichttekst Pagina P_ID, sleuf S_ID in object-ID O_ID, index-ID I_ID, partitie-ID PN_ID, alloc-eenheids-ID A_ID (type TYPE). De waarde van kolom COLUMN_NAME valt buiten het bereik voor het datatype "DATATYPE". Werk de kolom bij naar een juridische waarde.

Explanation

De kolomwaarde die in de opgegeven kolom staat, valt buiten het bereik van mogelijke waarden voor het kolomdatatype. Als je ongeldige gegevens in een tabelkolom hebt, kun je problemen ondervinden, afhankelijk van het type handelingen dat op de ongeldige data wordt uitgevoerd. Het is echter ook mogelijk dat er geen probleem optreedt, en dat de ongeldige data pas ontdekt wordt als je een DBCC CHECKDB or-commando DBCC CHECKTABLE uitvoert.

Enkele symptomen die je kunt opmerken door de aanwezigheid van ongeldige gegevens zijn onder andere (maar niet beperkt tot):

  • Toegangsschendingen of andere uitzonderingen bij het uitvoeren van zoekopdrachten op de getroffen kolom.
  • Onjuiste resultaten worden teruggegeven door zoekopdrachten die op de getroffen kolom zijn uitgevoerd.
  • Fouten of problemen wanneer statistieken worden opgebouwd tegen de getroffen kolom.
  • Foutmeldingen zoals het volgende:

    Msg 9100, Niveau 23, Toestand 2, Line <LineNum> Mogelijke indexcorruptie gedetecteerd. VOER DBCC CHECKDB uit.

DATA_PURITY controles

Wanneer je een DBCC CHECKDB- of DBCC CHECKTABLE-commando uitvoert, voert SQL Server "data purity"-validaties uit van kolomwaarden in elke rij van elke tabel in de database. Deze controles worden uitgevoerd om te verzekeren dat de waarden die in de kolommen zijn opgeslagen geldig zijn. Dat wil zeggen, de validatie zorgt ervoor dat de waarden niet buiten het bereik van het domein liggen dat aan het datatype van de kolommen is gekoppeld. De aard van de uitgevoerde validatie hangt af van het datatype van de kolom. De volgende niet-uitputtende lijst geeft enkele voorbeelden:

Kolomgegevenstype Type gegevensvalidatie uitgevoerd
Unicode-teken De datalengte moet een veelvoud van 2 zijn.
Datum/tijd Het datumveld zou moeten liggen tussen 1 januari 1753 en 31 december 9999. Het tijdsveld moet eerder zijn dan "23:59:59.997 PM."
Real en Float Controleer of er ongeldige floating-pointwaarden zijn zoals SNAN, QNAN, NINF, ND, PD en PINF.

Niet alle datatypen worden gecontroleerd op de geldigheid van de kolomgegevens. Alleen die welke mogelijk een opgeslagen waarde buiten bereik hebben, worden gecontroleerd. Het tinyint datatype heeft bijvoorbeeld een geldig bereik van 0 tot 255 en wordt opgeslagen in één byte (die alleen waarden tussen 0 en 255 kan opslaan), dus het controleren van de waarde is niet nodig.

Note

Deze controles zijn standaard ingeschakeld en kunnen niet worden uitgeschakeld, dus het is niet nodig om expliciet de DATA_PURITY-optie te gebruiken bij het uitvoeren van een DBCC CHECKDB or-commando DBCC CHECKTABLE . Als je echter de PHYSICAL_ONLY-optie met DBCC CHECKDB of DBCC CHECKTABLEgebruikt, worden er geen gegevenszuiverheidscontroles uitgevoerd.

DATA_PURITY probleemrapport

Wanneer je een DBCC CHECKDB or-commando DBCC CHECKTABLE uitvoert met de DATA_PURITY optie ingeschakeld (of de zuiverheidscontroles automatisch worden uitgevoerd), en er ongeldige gegevens bestaan in de tabellen die door de commando's DBCC worden gecontroleerd, zal de DBCC output andere berichten bevatten die de problemen met betrekking tot de data aangeven. De volgende voorbeeldfoutmeldingen geven problemen met de gegevenszuiverheid aan:

DBCC results for "account_history". 
Msg 2570, Level 16, State 2, Line <LineNum> 
Page (1:1073), slot 33 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "account_name" value is out of range for data type "nvarchar". Update column to a legal value. 
 
Msg 2570, Level 16, State 2, Line <LineNum> 
Page (1:1156), slot 120 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "account_name" value is out of range for data type "nvarchar". Update column to a legal value.
There are 153137 rows in 1080 pages for object "account_history". 
CHECKDB found 0 allocation errors and 338 consistency errors in table "account_history" (object ID <ObjectID>). 
CHECKDB found 0 allocation errors and 338 consistency errors in database '<DatabaseName>'. 
DBCC execution completed. If DBCC printed error messages, contact your system administrator. 

DBCC results for 'table1'. 
Msg 2570, Level 16, State 3, Line <LineNum> 
Page (1:154), slot 0 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "col2" value is out of range for data type "real". Update column to a legal value. 
There are 4 rows in 2 pages for object "table1". 
CHECKDB found 0 allocation errors and 1 consistency errors in table 'table1' (object ID <ObjectID>). 
CHECKDB found 0 allocation errors and 1 consistency errors in database 'realdata'. DBCC execution completed. If DBCC printed error messages, contact your system administrator. 

DBCC results for 'table2'. 
Msg 2570, Level 16, State 3, Line <LineNum> 
Page (1:155), slot 0 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "col2" value is out of range for data type "decimal". Update column to a legal value. 
There are 4 rows in 1 pages for object "table2". 
CHECKDB found 0 allocation errors and 1 consistency errors in table 'table2' (object ID <ObjectID>). 
CHECKDB found 0 allocation errors and 1 consistency errors in database 'realdata'. DBCC execution completed. If DBCC printed error messages, contact your system administrator. 

DBCC results for 'table3'. 
Msg 2570, Level 16, State 3, Line <LineNum> 
Page (1:157), slot 0 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "col2" value is out of range for data type "datetime". Update column to a legal value. 
There are 3 rows in 1 pages for object "table3". 
CHECKDB found 0 allocation errors and 1 consistency errors in table 'table3' (object ID <ObjectID>). 
CHECKDB found 0 allocation errors and 1 consistency errors in database 'realdata'. DBCC execution completed. If DBCC printed error messages, contact your system administrator. 

For every row that contains an invalid column value, a 2570 error is generated. 

Oorzaak

Ongeldige of buiten bereik gelegen gegevens kunnen om de volgende redenen in de SQL Server-database zijn opgeslagen:

  • Ongeldige gegevens werden in SQL Server ingevoerd via remote procedure call (RPC) gebeurtenissen.
  • Andere mogelijke oorzaken van corruptie van fysieke data maakten de kolomwaarde ongeldig.

Los het probleem van datazuiverheid op

De 2570-fouten kunnen niet worden hersteld met een van de DBCC reparatieopties. De reden is dat je DBCC niet kunt bepalen welke waarde gebruikt moet worden om de ongeldige kolomwaarde te vervangen. Daarom moet de kolomwaarde handmatig worden bijgewerkt. Om een handmatige update uit te voeren, moet je de rij vinden die het probleem heeft. Gebruik een van de volgende methoden om de rij te vinden:

  • Voer een query uit op de tabel die de ongeldige waarden bevat om de rijen te vinden die de ongeldige waarden bevatten.
  • Gebruik de informatie uit de foutmelding 2570 om de rijen te identificeren met ongeldige waarden.

Beide methoden worden in de volgende secties beschreven en geven voorbeelden om de rijen te vinden die ongeldige gegevens bevatten.

Zodra je de juiste rij hebt gevonden, moet er een beslissing worden genomen over de nieuwe waarde die gebruikt zal worden om de bestaande ongeldige data te vervangen. Deze beslissing moet zeer zorgvuldig worden genomen, gebaseerd op het bereik van waarden dat van toepassing is op de toepassing en de logische betekenis van die specifieke datarij. U hebt de volgende opties:

  • Als je weet welke waarde het moet zijn, stel het dan op die specifieke waarde in.
  • Stel het in op een acceptabele standaardwaarde.
  • Stel de kolomwaarde in op NULL.
  • Stel de kolomwaarde in op de maximale of minimale waarde voor dat datatype van de kolom.
  • Als je denkt dat de specifieke rij niet nuttig is zonder een geldige waarde voor de kolom, verwijder die rij dan helemaal.

Zoek rijen met ongeldige waarden met T-SQL-query's

Het type query dat je moet uitvoeren om rijen met ongeldige waarden te vinden, hangt af van het datatype van de kolom die een probleem rapporteert. Als je naar de foutmelding 2570 kijkt, zie je twee belangrijke informatie die je met dit probleem kan helpen. In het volgende voorbeeld is de waarde van de kolom account_name buiten bereik voor het datatype nvarchar. We kunnen gemakkelijk de kolom met het probleem identificeren en het datatype van de kolom die erbij betrokken is. Zodra je het datatype en de betrokken kolom kent, kun je zoekopdrachten formuleren om de rijen te vinden die ongeldige waarden voor die kolom bevatten, en de kolommen selecteren die nodig zijn om die rij (als de predicaten in een WHERE clausule) te identificeren voor verdere updates of verwijdering.

Unicode-datatype
SELECT col1, DATALENGTH(account_name) AS Length, account_name  
FROM account_history 
WHERE DATALENGTH(account_name) % 2 != 0
Type float data

Voer het volgende codefragment uit door te wisselen col1 naar de kolom(men) van je daadwerkelijke primaire sleutel, col2 naar de kolom van de 2570-fout, en table1 naar de tabel vanuit de CHECKDB uitvoer.

SELECT col1, col2 FROM table1 
WHERE col2<>0.0 AND (col2 < 2.23E-308 OR col2 > 1.79E+308) AND (col2 < -1.79E+308 OR col2 > -2.23E-308)
Reël datatype

Voer het volgende codefragment uit door te wisselen col1 naar de kolom(men) van je daadwerkelijke primaire sleutel, col2 naar de kolom van de 2570-fout, en table1 naar de tabel vanuit de CHECKDB uitvoer.

SELECT col1, col2 FROM testReal  
WHERE col2<>0.0 AND (col2 < CONVERT(real,1.18E-38) OR col2 > CONVERT(real,3.40E+38)) AND (col2 < CONVERT(real,-3.40E+38) OR col2 > CONVERT(real,-1.18E-38))  
ORDER BY col1; -- checks for real out of range 
Decimale en numerieke datatypen
SELECT col1 FROM table2 
WHERE col2 > 9999999999.99999  
OR col1 < -9999999999.99999

Houd er rekening mee dat je de waarden moet aanpassen op basis van de precisie en schaal waarmee je de decimal OF-kolom numeric hebt gedefinieerd. In het bovenstaande voorbeeld wordt de kolom gedefinieerd als col2 decimal(15,5).

Datum-tijddatatype

Je moet twee verschillende zoekopdrachten uitvoeren om de rijen te identificeren die ongeldige waarden voor de datetime kolom bevatten.

SELECT col1 FROM table3 
WHERE col2 < '1/1/1753 12:00:00 AM' OR col2 > '12/31/9999 11:59:59 PM' 

SELECT col1 FROM table3 WHERE 
((DATEPART(ms,col2)+ (1000*DATEPART(s,col2)) + (1000*60*DATEPART(mi,col2)) + (1000*60*60*DATEPART(hh,col2)))/(1000*0.00333))  > 25919999

Zoek rijen met ongeldige waarden met behulp van de fysieke locatie

Je kunt deze methode gebruiken als je de rijen met ongeldige waarden niet kunt vinden door de T-SQL-methode te gebruiken. In het foutbericht 2570 wordt de fysieke locatie van de rij die de ongeldige waarde bevat geprint. Kijk bijvoorbeeld naar het volgende bericht:

Page (1:157), slot 0 in object ID <ObjectID>, index ID 0, partition ID <PartitionID>, alloc unit ID <UnitID> (type "In-row data"). Column "col2" value is out of range for data type "datetime". Update column to a legal value. 

In dit bericht valt je op Page (1:157), slot 0. Het is de informatie die je nodig hebt om de rij te identificeren. Het FileId is, het 1 is PageInFile157en het SlotId is0.

Zodra je deze informatie hebt, moet je het volgende commando uitvoeren:

DBCC TRACEON (3604)
DBCC PAGE (realdata , 1 , 157 , 3)

Note

Dit commando print de volledige inhoud van een pagina af. De parameters van het DBCC PAGE commando zijn:

  • Database name: De naam van de database.
  • File number: Het bestandsnummer van het databasebestand.
  • Page number: Het nummer van de pagina die je wilt onderzoeken.
  • Print option: Een optionele parameter die het niveau van uitvoerdetail bepaalt.

Zodra je dit commando uitvoert, zie je een output die informatie bevat die vergelijkbaar is met het volgende formaat:

Slot 0  Offset 0x60 Length 19
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Memory Dump @0x44D1C060
00000000: 10001000 01000000 ffffffff ffffffff †................
00000010: 0200fc†††††††††††††††††††††††††††††††...
Slot 0 Column 0  Offset 0x4 Length 4  col1 = 1
Slot 0 Column 1  Offset 0x8 Length 8  col2 = Dec 31 1899 19:04PM
Slot 1 Offset 0x73 Length 19
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Memory Dump @0x44D1C073
00000000: 10001000 02000000 0ba96301 f8970000 †..........c.....
00000010: 0200fc†††††††††††††††††††††††††††††††...
Slot 1 Column 0 Offset 0x4 Length 4 col1 = 2
Slot 1 Column 1 Offset 0x8 Length 8 col2 = Jul 8 2006 9:34PM
Slot 2 Offset 0x86 Length 19
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Memory Dump @0x44D1C086
00000000: 10001000 03000000 0ba96301 f8970000 †..........c.....
00000010: 0200fc†††††††††††††††††††††††††††††††... 
Slot 2 Column 0 Offset 0x4 Length 4 col1 = 3
Slot 2 Column 1 Offset 0x8 Length 8 col2 = Jul 8 2006 9:34PM

In deze output kun je duidelijk de kolomwaarden voor de rij van interesse zien. In dit geval heb je de rij nodig die in de pagina is opgeslagen slot 0 . Uit de foutmelding weet je dat dat col2 degene is met het probleem. Je kunt dus de waarde van col1 for Slot 0 nemen en die als predicaat gebruiken in de WHERE clausule van je update- of delete-statement.

Warning

We raden aan om de eerste methode te gebruiken (dat wil zeggen, gebruik T-SQL-queries om de benodigde informatie te vinden). Gebruik het DBCC PAGE commando alleen als laatste redmiddel. Wees uiterst voorzichtig wanneer je dit commando gebruikt in een productieomgeving. Het wordt aanbevolen om de productiedatabase op een testserver te herstellen, alle benodigde informatie op te halen met DBCC PAGE, en vervolgens de updates op de productieserver uit te voeren. Zoals altijd, zorg ervoor dat je een back-up klaar hebt voor het geval er iets misgaat en je terug moet naar een eerdere kopie van de database.

Zie ook