Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Ошибка при добавлении полей таблицы.  [new]
Belkin
Member

Откуда: Рязань
Сообщений: 461
Всем добрый день.
Есть "закрытый" программный продукт, который упал в ошибку. При изучении логов стало понятно, что одна из причин - ошибка при добавлении полей таблицы. Сейчас в таблице 53 поля, добавляются следующие:
 ALTER TABLE erpdb.dbo.ttccom130100 add 
 t_comp_d NVARCHAR(20) DEFAULT '        ' NOT NULL,
 t_date_l DATETIME DEFAULT '1753-01-01' NOT NULL,
 t_dist_l NVARCHAR(30) DEFAULT N'' NOT NULL,
 t_e3ps_l NVARCHAR(255) DEFAULT '                                                                                                                                                                                                                                                       ' NOT NULL,
 t_enfe_l NVARCHAR(255) DEFAULT '                                                                                                                                                                                                                                                               ' NOT NULL,
 t_enfs_l NVARCHAR(255) DEFAULT '                                                                                                                                                                                                                                                               ' NOT NULL,
 t_fovn_l NVARCHAR(20) DEFAULT '                    ' NOT NULL,
 t_ftyp_l NVARCHAR(3) DEFAULT '   ' NOT NULL,
 t_sqco_l INTEGER DEFAULT 0 NOT NULL,t_trsq_l INTEGER DEFAULT 0 NOT NULL

Ошибка :
Msg 511, Level 16, State 1, Line 2
Cannot create a row of size 8192 which is greater than the allowable maximum row size of 8060.
The statement has been terminated.


Я создаю такую же таблицу, с индексами, ограничениями и заполняю ее той единственной строкой из исходной таблицы. Затем запускаю этот скрипт и он проходит успешно. Я уже не понимаю в чем проблема. Прошу помощи.
-----------
Андрей.
1 авг 14, 10:27    [16385716]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка при добавлении полей таблицы.  [new]
mrGuest
Guest
Андрей неплохо бы конечно указывать версию SQL Server.

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/2b82d5cf-58ab-47d5-888f-956938452c70/why-is-sql-2005-giving-a-msg-511-exceeded-max-row-size-of-8060-error?forum=sqldatabaseengine
автор
The query fails in SQL Server 2005 because the Database Engine evaluates the ORDER BY clause earlier than it evaluates the clause in SQL Server 2000, and because the query requests a very long char field in its result set. The worktable the Database Engine builds specifies one or more rows that exceed the limit of 8,060 bytes.

To run the query successfully, convert any long fields in the select list to the varchar(max) or nvarchar(max) data types by using CAST or CONVERT.
1 авг 14, 10:34    [16385739]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка при добавлении полей таблицы.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
Belkin,

а ansi_padding как установлен? когда вы выполняете (из ssms?) и при выполнении из "программного продукта".
при создании таблицы тоже, кстати.

собственно, по sys.columns можно проверить, как была эта опция установлена при создании столбца.
текущее значение есть в sys.dm_exec_connections.
1 авг 14, 10:59    [16385861]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка при добавлении полей таблицы.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
daw,

хотя, нет, стоп. у этого приложения, случаем, нет привычки регулярно добавлять/удалять столбцы в таблице?
1 авг 14, 11:04    [16385892]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка при добавлении полей таблицы.  [new]
Belkin
Member

Откуда: Рязань
Сообщений: 461
daw
daw,

хотя, нет, стоп. у этого приложения, случаем, нет привычки регулярно добавлять/удалять столбцы в таблице?

Привычки такой нет. Есть операция, которая может это делать. И действительно такая операция выполнялась раз 5 подряд.
Я не понял в чем причина, но сделал так.
Удалил запись из таблицы и вставил туда данные из заранее скопированной таблицы. После этого ALTER TABLE по добавлению колонок прошел успешно.
1 авг 14, 11:29    [16386066]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка при добавлении полей таблицы.  [new]
o-o
Guest
вопрос к daw
daw, а можете помочь с воспроизведением?
у меня фантазия иссякла.
т.е. я могу воспроизвести, чтобы не дал более ни одной колонки вставить при кажущемся наличии места.
"забиваю" страницу "под завязку" колонками фиксир.длины,
неск. раз удаляю/создаю столбец, разумеется, никто с удаленного место не чистит, лимит 8060 достигается,
вот репро:
if object_id('dbo.t') is not null drop table dbo.t;
create table dbo.t (id int identity, col1 char(500), col2 char(500), col3 char(6040), col4 varchar(500));
 
alter table dbo.t 
drop column col1

alter table dbo.t 
add col1 char(500)

alter table dbo.t 
drop column col2

alter table dbo.t 
add col2 char(500) 

--Record Size = 8056
/*Warning: The table "t" has been created, but its maximum row size exceeds the allowed maximum of 8060 bytes. INSERT or UPDATE to this table will fail if the resulting row exceeds the size limit.*/

insert into dbo.t(col1, col2, col3, col4)
values (REPLICATE('1', 500), REPLICATE('2', 500), REPLICATE('3', 6040), '4')

alter table dbo.t 
add t_date_l DATETIME DEFAULT '1753-01-01' NOT NULL
    

/*Warning: The table "t" has been created, but its maximum row size exceeds the allowed maximum of 8060 bytes. INSERT or UPDATE to this table will fail if the resulting row exceeds the size limit.
Msg 511, Level 16, State 1, Line 1
Cannot create a row of size 8064 which is greater than the allowable maximum row size of 8060.
The statement has been terminated.
*/

т.е. тут кажется, что еще минимум килобайт есть в строке,
на самом деле мои 2 удаления по 500 байт этот килобайт успешно оттяпали,
вот подробная картинка страницы:
+

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
id = 1

Slot 0 Column 67108865 Offset 0x0 Length 0 Length (physical) 0
DROPPED = [NULL]

Slot 0 Column 67108866 Offset 0x0 Length 0 Length (physical) 0
DROPPED = [NULL]

Slot 0 Column 4 Offset 0x3f0 Length 6040 Length (physical) 6040
col3 = 333...

Slot 0 Column 5 Offset 0x1f77 Length 1 Length (physical) 1
col4 = 4

Slot 0 Column 6 Offset 0x1b88 Length 500 Length (physical) 500
col1 = 111...

Slot 0 Column 7 Offset 0x1d7c Length 500 Length (physical) 500
col2 = 222...



НО: как ТС умудрился высвободить место, удалив строку?
у меня была идея сыграть на столбце с varchar, раз переменной длины,
сперва записать "выпирающее" за страницу значение, чтоб его выкинуло как row-overflow на новую страницу, а на исходную только указатель.
и чтоб при этом страница достигла 8060 байт.
потом "обновить" значением "покороче", скажем, в 1 символ,
думаю, ну он его обновит на второй странице.
потом буду добавлять колонку, она не влезет, ок, удалю строку, добавлю столбец,
потом вставлю строку с тем "коротким" односимвольным значением для и строка влезет, ибо 1 символ, а не указатель на блоб там будет.
но шиш.
до "обновления" все получилось, а при обновлении он не ту новую row-overflow-страницу обновил, а заместо указателя
на исходной странице новое короткое значение поместил, так что еще один столбец позволил создать.

как еще вынудить его выдать ошибку, что в строку не лезет, а потом удалить строку и вдруг позволит столбец вставить?

если кто-то знает и не лень поделиться, плиз, расшарьте репро-код
4 авг 14, 19:10    [16398088]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить