MSSQLSERVER_2570
Область применения: SQL Server
Сведения
Атрибут | Значение |
---|---|
Название продукта | SQL Server |
ИД события | 2570 |
Источник событий | MSSQLSERVER |
Компонент | SQLEngine |
Символическое имя | DBCC_COLUMN_VALUE_OUT_OF_RANGE |
Текст сообщения | Страница P_ID, область памяти S_ID в идентификаторе объекта O_ID, идентификатор индекса I_ID, идентификатор секции PN_ID, идентификатор единицы распределения A_ID (тип TYPE). Значение столбца COLUMN_NAME вне допустимого диапазона типа данных «DATATYPE». Замените значение столбца на допустимое. |
Описание
Значение столбца, содержащееся в указанном столбце, выходит за пределы диапазона возможных значений для типа данных столбца. Если у вас есть недопустимые данные в столбце таблицы, могут возникнуть проблемы в зависимости от типа операций, выполняемых с недопустимыми данными. Однако также возможно, что проблема не появится, и недопустимые данные не будут обнаружены до тех пор, пока не выполните команду DBCC CHECKDB
или DBCC CHECKTABLE
не выполните команду.
Некоторые симптомы могут возникнуть из-за наличия недопустимых данных (но не ограничиваются):
- Нарушения доступа или другие исключения при выполнении запросов к затронутму столбцу.
- Неверные результаты, возвращаемые запросами, выполняемыми в затронутом столбце.
- Ошибки или проблемы при построении статистики в затронутом столбце.
- Сообщения об ошибках, как показано ниже:
Msg 9100, Level 23, State 2, LineNum <> Возможное повреждение индекса. Выполните инструкцию DBCC CHECKDB.
проверки DATA_PURITY
При выполнении команды DBCC CHECKDB или DBCC CHECKTABLE SQL Server выполняет проверку значений столбцов в каждой строке каждой таблицы в базе данных. Эти проверки выполняются, чтобы убедиться, что значения, хранящиеся в столбцах, являются допустимыми. То есть проверка гарантирует, что значения не являются вне диапазона домена, связанного с типом данных столбцов. Характер выполняемой проверки зависит от типа данных столбца. В следующем неисчерпаемом списке приведены некоторые примеры:
Тип данных столбца | Тип выполняемой проверки данных |
---|---|
символьный формат Юникода | Длина данных должна быть кратной из 2. |
Datetime | Поле даты должно быть от 1 января 1753 г. до 31 декабря 9999 г. Поле времени должно быть более ранним, чем "11:59:59.997PM". |
Реальный и плавающий | Проверьте наличие недопустимых значений с плавающей запятой, таких как SNAN, QNAN, NINF, ND, PD и PINF. |
Не все типы данных проверяются на допустимость данных столбца. Проверяются только те, у которых может быть вне диапазона хранимое значение. Например, tinyint
тип данных имеет допустимый диапазон от 0 до 255 и хранится в одном байте (который может хранить только значения от 0 до 255), поэтому проверка значения не требуется.
Примечание.
Эти проверки включены по умолчанию и не могут быть отключены, поэтому не нужно явно использовать параметр DATA_PURITY при выполнении DBCC CHECKDB
команды или DBCC CHECKTABLE
выполнения команды. Однако при использовании параметра DBCC CHECKDB
PHYSICAL_ONLY или DBCC CHECKTABLE
проверки чистоты данных не выполняются.
отчет о проблемах DATA_PURITY
При выполнении команды DATA_PURITY
с DBCC CHECKTABLE
включенным параметром DBCC CHECKDB
(или проверки чистоты данных выполняются автоматически), а недопустимые данные существуют в таблицах, проверенных 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 по следующим причинам:
- Недопустимые данные были вставлены в SQL Server с помощью событий удаленного вызова процедур (RPC).
- Другие потенциальные причины повреждения физических данных сделали значение столбца недопустимым.
Устранение проблемы с чистотой данных
Ошибки 2570 не могут быть исправлены с помощью каких-либо DBCC
вариантов восстановления. Причина заключается в том, что DBCC
не удается определить, какое значение следует использовать для замены недопустимого значения столбца. Таким образом, значение столбца должно быть обновлено вручную. Чтобы выполнить обновление вручную, необходимо найти строку, которая имеет проблему. Используйте один из следующих методов для поиска строки:
- Выполните запрос к таблице, содержащей недопустимые значения, чтобы найти строки, содержащие недопустимые значения.
- Используйте сведения из ошибки 2570, чтобы определить строки, имеющие недопустимые значения.
Оба метода подробно описаны в следующих разделах и приведены примеры для поиска строк с недопустимыми данными.
После поиска правильной строки необходимо принять решение о новом значении, которое будет использоваться для замены существующих недопустимых данных. Это решение должно быть принято очень тщательно, основываясь на диапазоне значений, применимых к приложению, и логическом значении этой конкретной строки данных. Доступны следующие варианты.
- Если вы знаете, какое значение должно быть, задайте для него конкретное значение.
- Задайте для него допустимое значение по умолчанию.
- Задайте для столбца значение
NULL
. - Задайте значение столбца максимальному или минимальному значению этого типа данных столбца.
- Если вы считаете, что конкретная строка не полезна без допустимого значения для столбца, удалите эту строку полностью.
Поиск строк с недопустимыми значениями с помощью запросов T-SQL
Тип запроса, который необходимо выполнить, чтобы найти строки с недопустимыми значениями, зависят от типа данных столбца, сообщающего о проблеме. При просмотре сообщения об ошибке 2570 вы заметите два важных фрагмента информации, которые помогут вам с этой проблемой. В следующем примере значение столбца account_name
выходит за пределы диапазона для типа nvarchar
данных. Можно легко определить столбец с проблемой и типом данных связанного столбца. Таким образом, после того как вы знаете тип данных и столбец, можно сформулировать запросы, чтобы найти строки, содержащие недопустимые значения для этого столбца, и выбрать столбцы, необходимые для идентификации этой строки (как предикаты в WHERE
предложении) для дальнейшего обновления или удаления.
Тип данных Юникода
SELECT col1, DATALENGTH(account_name) AS Length, account_name
FROM account_history
WHERE DATALENGTH(account_name) % 2 != 0
Тип данных Float
Запустите следующий фрагмент кода, изменив col1
фактические столбцы первичного ключа, col2
на столбец из ошибки 2570 и 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)
Реальный тип данных
Запустите следующий фрагмент кода, изменив col1
фактические столбцы первичного ключа, col2
на столбец из ошибки 2570 и 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
157
, PageInFile
и 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
в качестве предиката в WHERE
предложении инструкции обновления или удаления.
Предупреждение
Мы рекомендуем использовать первый метод (т. е. использовать запросы T-SQL для поиска необходимых сведений). DBCC PAGE
Используйте команду только в качестве последнего средства. При использовании этой команды в рабочей среде необходимо обеспечить максимальную осторожность. Рекомендуется восстановить рабочую базу данных на тестовом сервере, получить все необходимые сведения, а DBCC PAGE
затем выполнить обновления на рабочем сервере. Как всегда, убедитесь, что резервная копия готова, если что-то пошло не так, и вам нужно вернуться к более ранней копии базы данных.