疑難排解在 SQL Server 2005 和更新版本的 DBCC 錯誤 2570

適用於: Microsoft SQL Server 2005 Standard EditionMicrosoft SQL Server 2005 Developer EditionMicrosoft SQL Server 2005 Enterprise Edition

簡介


本文將告訴 SQL Server 錯誤 2570年、 什麼造成錯誤,以及如何解決問題。

更多的資訊


DATA_PURITY 檢查

在 SQL Server 2005,新的選項︰ DATA_PURITY,已經新增的 DBCC CHECKDB,在於命令。當您執行 DBCC CHECKDB 或在於命令以啟用此選項時,則指令會執行 「 資料單純性"驗證中所有的資料列的資料表或資料庫中的資料表的每個資料行值。若要確保儲存在資料行的值是有效執行這些新的檢查 (也就是這些值不會跨範圍網域相關聯的資料型別,該資料行的)。執行驗證的本質,取決於資料行的資料型別。下列的非詳盡清單會提供一些範例︰
資料行資料型別執行資料驗證的型別
Unicode 字元資料長度應為 2 的倍數。
日期時間[天] 欄位應該是介於 Jan 1 1753年到 12 月 31 日到 9999。「 時間 」 欄位必須是早於 '11:59:59:999 PM'。
實際測量及抹請檢查存在無效浮點值像 SNAN、 QNAN、 NINF,ND、 PD、 PINF。
並非所有的資料型別會檢查有資料行資料的有效性。只可以有預存的值超出範圍,會檢查。例如, tinyint資料型別有 0 到 255 之間的有效範圍,而會儲存在單一位元組 (這只能儲存從 0 到 255 之間的值),因此檢查的值不是必要的功能。

資料的單純性驗證檢查不會自動啟用所有資料庫中。視幾個因素而定,會啟用檢查︰
  • 對於在 SQL Server 2005 及更新版本中建立的資料庫,這些檢查會預設成啟用狀態,且無法停用,因此使用 DATA_PURITY 選項執行 DBCC CHECKDB 或在於命令時是不相關。
  • 在舊版的 SQL Server,例如 SQL Server 2000年、 SQL Server 7.0 中,以及版本升級至 SQL Server 2005,所建立的資料庫預設不會啟用這些檢查項目。為了讓執行這些檢查項目,您必須指定 DBCC CHECKDB 或在於命令中的 [DATA_PURITY] 選項。這可能會導致兩件事︰
    • DBCC 命令完成,並報告資料庫是乾淨的包括所有的資料單純性檢查。這項事實會記錄在資料庫標頭。所有後續 DBCC CHECKDB 或在於命令的執行會注意到這項資訊,並會自動執行資料單純性檢查,如會發生在 SQL Server 2005 上建立的資料庫。換句話說,一旦資料庫已知為 「 乾淨 」 時,資料的單純性檢查一定會執行。
    • DBCC 命令完成,但是資料不一致的相關報告問題。如果發生這種情形,您將必須清除要移除的不一致的資料庫,並嘗試再次執行 DBCC 命令。您必須指定 DBCC 命令的 [DATA_PURITY] 選項,直到資料庫報告為初始狀態。
  • 如果 DBCC CHECKDB 或在於命令執行時指定 [PHYSICAL_ONLY] 選項,則不會執行資料的單純性檢查。

徵狀

無效或超出範圍的資料可能儲存在舊版的 SQL Server 資料庫中,原因如下︰
  • 無效的資料是在來源中使用大量插入的方法,例如,bcp 公用程式時出現。
  • 透過對 SQL Server 的 RPC 事件呼叫傳遞無效的資料。
  • 其他可能的原因左實體資料損毀的資料行值處於無效狀態。
如果您在資料表的資料行中有無效的資料,您可能會遇到問題,視針對無效的資料執行的作業類型而定。不過,也很可能會出現任何問題,而並不會發現無效的資料,直到您在 SQL Server 2005 及更新版本上執行 DBCC CHECKDB 或在於命令。

一些您可能會注意到,因為不正確的資料存在的徵狀包括 (但並不限於)︰
  • 存取違規或其他類型的執行受影響的資料行的查詢時的例外狀況。
  • 針對受影響的資料行執行的查詢所傳回的結果不正確。
  • 錯誤或問題時正在建置針對受影響的資料行統計資料。
  • 如下所示的錯誤訊息︰
    訊息 9100,層級 23 狀態 2,行 1 偵測到的索引可能損毀。執行 DBCC CHECKDB。

DATA_PURITY 問題報告

當您執行 DBCC CHECKDB 或命令以啟用 [DATA_PURITY] 選項 (或自動執行檢查資料純度),及不正確的在於資料存在於被 DBCC 命令的資料表時,DBCC 輸出包含額外的訊息,指出資料有問題。有些範例錯誤訊息,指出資料單純性問題如下所示︰
"Account_history"的 DBCC 結果。
訊息 2570,層次 16,狀態 2,行 1
網頁 (1:1073),插槽 33 中物件 ID 1977058079,索引識別碼 0、 磁碟分割識別碼 129568478265344、 配置單位識別碼 129568478265344 (型別 「 同資料列資料 」)。資料行"account_name_japan"的值超出資料型別"nvarchar"的範圍。合法值的 [更新] 欄位。

訊息 2570,層次 16,狀態 2,行 1
網頁 (1:1156),插槽 120 中物件 ID 1977058079,索引識別碼 0、 磁碟分割識別碼 129568478265344、 配置單位識別碼 129568478265344 (型別 「 同資料列資料 」)。資料行"account_name_japan"的值超出資料型別"nvarchar"的範圍。合法值的 [更新] 欄位。
物件"account_history"的 1080年頁面中有 153137 的資料列。
CHECKDB 表"account_history"(物件 ID 1977058079) 得 0 的配置錯誤和 338 一致性錯誤。
CHECKDB 會在資料庫 'BadUnicodeData' 中找到 0 的配置錯誤和 338 一致性錯誤。
DBCC 執行完畢。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。
'Table1' 的 DBCC 結果。
訊息 2570,層次 16,狀態 3,第 1 行
網頁 (1:154)、 插槽 0 中的物件 ID 2073058421,索引識別碼 0、 磁碟分割識別碼 72057594038321152、 配置單位識別碼 72057594042318848 (型別 「 同資料列資料 」)。資料行 」 欄 2"的值超出 「 真正 」 的資料類型的範圍。合法值的 [更新] 欄位。
物件"table1"2 頁中有 4 個資料列。
0 的配置錯誤和 1 的一致性錯誤在資料表 'table1' (物件 ID 2073058421),就會找到 CHECKDB。
CHECKDB 會位於資料庫 'realdata' 0 的配置錯誤和 1 的一致性錯誤。DBCC 執行完畢。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。
'Table2' 的 DBCC 結果。
訊息 2570,層次 16,狀態 3,第 1 行
網頁 (1:155)、 插槽 0 中的物件 ID 2105058535,索引識別碼 0、 磁碟分割識別碼 72057594038452224、 配置單位識別碼 72057594042449920 (型別 「 同資料列資料 」)。資料行 」 欄 2"的值超出 「 十進位 」 的資料類型的範圍。合法值的 [更新] 欄位。
物件"table2"的 1 頁面中有 4 個資料列。
0 的配置錯誤和 1 的一致性錯誤 'table2' 資料表中 (物件 ID 2105058535),就會找到 CHECKDB。
CHECKDB 會位於資料庫 'realdata' 0 的配置錯誤和 1 的一致性錯誤。DBCC 執行完畢。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。
'Table3' 的 DBCC 結果。
訊息 2570,層次 16,狀態 3,第 1 行
網頁 (1:157)、 插槽 0 中的物件 ID 2121058592,索引識別碼 0、 磁碟分割識別碼 72057594038517760、 配置單位識別碼 72057594042515456 (型別 「 同資料列資料 」)。資料行 」 欄 2"的值超出資料型別"日期時間 」 的範圍。合法值的 [更新] 欄位。
1 物件"table3 」 頁面中有 3 個資料列。
0 的配置錯誤和 1 的一致性錯誤在資料表 'table3' (物件 ID 2121058592),就會找到 CHECKDB。
CHECKDB 會位於資料庫 'realdata' 0 的配置錯誤和 1 的一致性錯誤。DBCC 執行完畢。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。
每個資料列包含無效的資料行值,就會產生 2570年錯誤。

修復資料的單純性問題

無法使用任一 DBCC 修復選項,修復 2570年錯誤。這是因為它是不可能判斷什麼值應該用來取代無效的資料行值的 DBCC。因此,您必須以手動方式更新這項資料行的值。

若要執行手動的更新,您必須尋找問題的那一列。有兩種方式可以完成這項作業。
  • 對執行查詢包含無效的值,以尋找包含無效的值的資料列的資料表。
  • 您可以使用 [從 2570年錯誤的資訊來識別包含無效的值的資料列。
我們將討論這兩種方法,詳細說明,以尋找具有無效的資料列中使用範例。

一旦您找到正確的資料列時,決定必須設為新的值會用來取代現有的無效資料。這個決定也適用於應用程式的值的範圍上進行非常仔細地根據以及有何邏輯適合該資料列的資料。您必須選擇如下︰
  • 如果您知道它應該是什麼值,設定該特定的值。
  • 請將它設定為可接受的預設值。
  • 設定為 NULL 的資料行的值。
  • 資料行的值設為該資料型別,資料行的最大或最小值。
  • 如果您覺得特定的資料列不屬於任何不含有效的值資料行的使用,您可以完全刪除該資料列。

尋找與使用 T SQL 查詢的值不正確的資料列

您需要執行來尋找具有無效值的資料列的查詢類型是根據報告問題的資料行的資料型別而定。如果您看一下 2570年錯誤訊息,您會注意到兩個重要部分,協助您達成這個資訊。在下列範例中,資料行"account_name_japan"的值超出範圍的資料型別"nvarchar"。我們可以輕鬆地識別有問題,以及相關的資料行的資料型別資料行。因此,一旦您知道的資料型別所涉及的資料行,您可以制定查詢來尋找包含無效的值,為該資料行的資料列,選取資料行所需的任何進一步更新或刪除,識別該資料列 (做為 WHERE 子句中述詞)。

Unicode 資料型別︰
SELECT col1 ,DATALENGTH(account_name_japan) as Length ,account_name_japan 
FROM account_history
WHERE DATALENGTH(account_name_japan) % 2 != 0

浮點數資料型別︰
-- Change col1 to your actual primary key column(s), col2 to the column from the 2570 error, table1 to the table from the CHECKDB output

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)

實際的資料型別︰
-- Change col1 to your actual primary key column(s), col2 to the column from the 2570 error, table1 to the table from -- the CHECKDB output

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
請注意,您將需要調整為基礎的位數和小數位數與您已定義了小數或數字的資料行的值。在上述範例中,資料行定義為第 2 欄 decimal(15,5)。

日期時間資料型別︰
您必須執行兩個不同的查詢,來識別包含無效的值,日期時間資料行的資料列。
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年錯誤訊息中,會列印包含無效的值的資料列的實體位置。例如,查看下列訊息︰
網頁 (1:157)、 插槽 0 中的物件 ID 2121058592,索引識別碼 0、 磁碟分割識別碼 72057594038517760、 配置單位識別碼 72057594042515456 (型別 「 同資料列資料 」)。資料行 」 欄 2"的值超出資料型別"日期時間 」 的範圍。合法值的 [更新] 欄位。
在這個訊息中,您會注意到的資訊︰ 頁面 (1:157),0 位置。這是您需要識別資料列的資訊。FileId 是 1,PageInFile 是 157,而 Rid 為 0。一旦您知道此資訊時,您必須執行命令,如下︰
DBCC TRACEON ( 3604 )
DBCC PAGE ( realdata , 1 , 157 , 3 )
這個命令將會列印整個網頁的內容。DBCC PAGE 命令的參數為︰
  • 資料庫名稱
  • FileId
  • PageInFile
  • 列印選項
一旦您執行此命令時,您會注意到包含類似下列的格式資訊的輸出︰
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
在這個輸出中,您可以清楚地看到您有興趣的資料列的資料行值。在此情況下,您必須儲存在頁面的插槽 0 的資料列。從錯誤訊息,您知道該第 2 欄會有問題。因此您可以採用欄 1 的值,對於位置 0,並作為您的 update 陳述式的 WHERE 子句中的述詞或刪除陳述式。

警告我們建議您使用第一種方法 (也就是使用 T SQL 查詢,尋找所需的資訊)。使用 DBCC PAGE 命令只做為最後的手段。採用具有特別小心,但是您在生產環境中使用這個命令。建議以還原的實際執行資料庫,在測試伺服器,然後取得所有必要的資訊使用 DBCC PAGE,然後執行 [實際執行伺服器上的更新。同樣的請確定將備份準備好,以防萬一有任何差錯,而且您需要回到而較舊的資料庫。

參考


如需有關的 DBCC CHECKDB 陳述式的詳細資訊,請參閱下列 Microsoft 開發人員網路 (MSDN) 網站上的"DBCC CHECKDB (考慮改用 SQL) 」 主題︰如需有關 SQL Server 2000年中的已知問題的詳細資訊,請按一下下面的文件編號,檢視 「 Microsoft 知識庫 」 中的文件︰
900335修正︰ SQL Server 2000年自動資料庫復原作業不成功,如果索引會包含 FLOAT 資料型別或 REAL 資料型別,而這個資料型別包含與 NaN 值

如需有關 RPC 事件的詳細資訊,請參閱下列 MSDN 網站上的 「 呼叫預存程序 (OLE DB) 」 的主題︰如需有關不同的資料類型的詳細資訊,請參閱下列 MSDN 網站上的 「 呼叫預存程序 (OLE DB) 」 的主題︰如需有關浮動的點值慣例的詳細資訊,請造訪下列 Intel 網站︰Microsoft 提供協力廠商連絡資訊,以協助您尋找技術支援。此連絡資訊可能會變更不另行通知。Microsoft 不保證此第三方連絡資訊的正確性。