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 CHECKDB
或 DBCC CHECKTABLE
命令之前,將不會探索到無效的數據。
由於數據無效,您可能會注意到某些徵兆(但不限於):
- 對受影響的數據行執行查詢時,存取違規或其他例外狀況。
- 針對受影響數據行執行的查詢所傳回的結果不正確。
- 針對受影響的數據行建置統計數據時發生錯誤或問題。
- 錯誤訊息,如下所示:
偵測到 Msg 9100、Level 23、State 2、Line LineNum <> 可能索引損毀。 請執行 DBCC CHECKDB。
DATA_PURITY檢查
當您執行 DBCC CHECKDB 或 DBCC 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 CHECKDB
或 DBCC 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
為數據行,以及table1
從CHECKDB
輸出變更為數據表,以執行下列代碼段。
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
為數據行,以及table1
從CHECKDB
輸出變更為數據表,以執行下列代碼段。
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
請記住,您必須根據您已定義 decimal
或 numeric
數據行的有效位數和小數字數來調整值。 在上述範例中,資料行定義為 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
。 這是識別數據列所需的資訊。 FileId
是 1
,PageInFile
是 157
,而 SlotId
是 0
。
擁有這項資訊之後,您必須執行下列命令:
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
這是有問題的訊息。 因此,您可以接受的值col1
Slot 0
,並將其當做 update 語句的 子句中的WHERE
述詞,或 delete 語句。
警告
我們建議您使用第一個方法(也就是,使用 T-SQL 查詢來尋找必要資訊)。 只使用 DBCC PAGE
命令做為最後手段。 在生產環境中使用此命令時,請盡最大努力。 建議您在測試伺服器上還原生產資料庫、使用 DBCC PAGE
取得所有必要的資訊,然後在生產伺服器上執行更新。 一如往常,請務必讓備份保持就緒,以防發生問題,而您需要還原為先前的資料庫複本。