分享方式:


MSSQLSERVER_2570

適用於:SQL Server

詳細資料

屬性
產品名稱 SQL Server
事件識別碼 2570
事件來源 MSSQLSERVER
元件 SQLEngine
符號名稱 DBCC_COLUMN_VALUE_OUT_OF_RANGE
訊息文字 頁面P_ID、對象標識碼O_ID、索引標識碼I_ID、分割區標識碼PN_ID、配置單位標識碼A_ID中的位置S_ID(類型 TYPE)。 數據行COLUMN_NAME值超出數據類型 「DATATYPE」 的範圍。 請將資料行更新為合法的值。

說明

包含在指定數據行中的數據行值超出數據行數據類型的可能值範圍。 如果您在數據表數據行中有無效的數據,可能會發生問題,視針對無效數據執行的作業類型而定。 不過,也可能不會出現任何問題,而且在您執行 DBCC CHECKDBDBCC CHECKTABLE 命令之前,將不會探索到無效的數據。

由於數據無效,您可能會注意到某些徵兆(但不限於):

  • 對受影響的數據行執行查詢時,存取違規或其他例外狀況。
  • 針對受影響數據行執行的查詢所傳回的結果不正確。
  • 針對受影響的數據行建置統計數據時發生錯誤或問題。
  • 錯誤訊息,如下所示:

    偵測到 Msg 9100、Level 23、State 2、Line LineNum <> 可能索引損毀。 請執行 DBCC CHECKDB。

DATA_PURITY檢查

當您執行 DBCC CHECKDBDBCC CHECKTABLE 命令時,SQL Server 會在資料庫中每個數據表的每個數據列中執行數據行值的「數據純潔性」驗證。 系統會執行這些檢查,以確保儲存在數據行中的值有效。 也就是說,驗證可確保值不會超出與數據行數據類型相關聯的定義域範圍。 執行的驗證本質取決於數據行的數據類型。 下列非詳盡清單提供一些範例:

資料行資料類型 執行的數據驗證類型
Unicode 字元 數據長度應該是 2 的倍數。
Datetime 日期字段應介於 1753 年 1 月 1 日到 9999 年 12 月 31 日之間。 時間字段必須早於 「11:59:59.997PM」。。
實際和浮點數 檢查是否有無效的浮點值,例如SNAN、QNAN、NINF、ND、PD 和 PINF。

並非所有數據類型都會檢查數據行數據的有效性。 只會檢查可能具有超出範圍的預存值。 例如, tinyint 數據類型的有效範圍是 0 到 255,並且儲存在單一位元組中(這只能儲存介於 0 到 255 之間的值),因此檢查值並非必要。

注意

默認會啟用這些檢查,而且無法停用,因此在執行 或 DBCC CHECKTABLE 命令時DBCC CHECKDB,不需要明確使用 DATA_PURITY 選項。 不過,如果您使用 PHYSICAL_ONLY 選項搭配 DBCC CHECKDBDBCC CHECKTABLE,則不會執行數據純潔度檢查。

DATA_PURITY問題報告

當您執行 DBCC CHECKDB 已啟用 選項的 或 DBCC CHECKTABLE 命令 DATA_PURITY 時(或數據純潔度檢查會自動執行),且命令所 DBCC 檢查的數據表中存在無效的數據時, DBCC 輸出會包含其他訊息,指出與數據相關的問題。 下列範例錯誤訊息指出數據純潔性問題:

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. 

原因

無效或超出範圍的數據可能已儲存在 SQL Server 資料庫中,原因如下:

  • 透過遠端過程調用 (RPC) 事件,將資料插入 SQL Server 中無效。
  • 實體數據損毀的其他可能原因使數據行值無效。

修正數據純潔性問題

無法使用任何 DBCC 修復選項來修復 2570 錯誤。 原因是 DBCC 無法判斷應該使用哪些值來取代無效的數據行值。 因此,數據行值必須手動更新。 若要執行手動更新,您必須找出有問題的數據列。 使用下列其中一種方法來尋找資料列:

  • 針對包含無效值的數據表執行查詢,以尋找包含無效值的數據列。
  • 使用錯誤 2570 中的資訊來識別具有無效值的數據列。

下列各節會詳細說明這兩種方法,並提供範例來尋找具有無效數據的數據列。

找到正確的數據列之後,必須針對將用來取代現有無效數據的新值做出決策。 必須根據適用於應用程式的值範圍,以及該特定數據列的邏輯意義,非常謹慎地做出此決定。 下列選項可供您選擇:

  • 如果您知道它應該的值,請將它設定為該特定值。
  • 將它設定為可接受的預設值。
  • 將資料列值設定為 NULL
  • 將數據行值設定為數據行數據類型的最大值或最小值。
  • 如果您認為特定數據列沒有資料行的有效值就沒有用處,請完全刪除該數據列。

使用 T-SQL 查詢尋找具有無效值的數據列

您需要執行的查詢類型,以尋找具有無效值的數據列,取決於報告問題的數據行數據類型。 如果您查看 2570 錯誤訊息,您會注意到兩個重要資訊,可協助您解決此問題。 在下列範例中,數據類型 的數據行 account_name 值超出範圍 nvarchar。 我們可以輕鬆地識別有問題的數據行,以及涉及之數據行的數據類型。 因此,一旦您知道數據類型和涉及的數據行之後,您可以制定查詢來尋找包含該數據行無效值的數據列,並選取識別該數據列所需的數據行(作為 子句中的述詞),以進行任何進一 WHERE 步的更新或刪除。

Unicode 數據類型
SELECT col1, DATALENGTH(account_name) AS Length, account_name  
FROM account_history 
WHERE DATALENGTH(account_name) % 2 != 0
Float 數據類型

將 變更為實際主鍵數據行、col2從 2570 錯誤變更col1為數據行,以及table1CHECKDB輸出變更為數據表,以執行下列代碼段。

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)
實際數據類型

將 變更為實際主鍵數據行、col2從 2570 錯誤變更col1為數據行,以及table1CHECKDB輸出變更為數據表,以執行下列代碼段。

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 
十進位和數值數據類型
SELECT col1 FROM table2 
WHERE col2 > 9999999999.99999  
OR col1 < -9999999999.99999

請記住,您必須根據您已定義 decimalnumeric 數據行的有效位數和小數字數來調整值。 在上述範例中,資料行定義為 col2 decimal(15,5)

Datetime 數據類型

您必須執行兩個不同的查詢,以識別包含數據行值無效的數據 datetime 列。

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

使用實體位置尋找具有無效值的數據列

如果您使用 T-SQL 方法找不到具有無效值 的數據列,您可以使用這個方法。 在 2570 錯誤訊息中,列印包含無效值之數據列的實體位置。 例如,查看下列訊息:

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. 

這個訊息中,您會注意到 Page (1:157), slot 0。 這是識別數據列所需的資訊。 FileId1PageInFile157,而 SlotId0

擁有這項資訊之後,您必須執行下列命令:

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

注意

此命令會列印頁面的整個內容。 命令的參數 DBCC PAGE 如下:

  • Database name:資料庫的名稱。
  • File number:資料庫檔案的檔案編號。
  • Page number:您要檢查的頁碼。
  • Print option:決定輸出詳細數據層級的選擇性參數。

執行此指令之後,您會注意到包含類似下列格式信息的輸出:

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

在此輸出中,您可以清楚地看到感興趣的數據列數據行值。 在此情況下,您需要儲存在 slot 0 頁面中的數據列。 從錯誤訊息中,您知道 col2 這是有問題的訊息。 因此,您可以接受的值col1Slot 0,並將其當做 update 語句的 子句中的WHERE述詞,或 delete 語句。

警告

我們建議您使用第一個方法(也就是,使用 T-SQL 查詢來尋找必要資訊)。 只使用 DBCC PAGE 命令做為最後手段。 在生產環境中使用此命令時,請盡最大努力。 建議您在測試伺服器上還原生產資料庫、使用 DBCC PAGE取得所有必要的資訊,然後在生產伺服器上執行更新。 一如往常,請務必讓備份保持就緒,以防發生問題,而您需要還原為先前的資料庫複本。

另請參閱