SQL Server 2012 – 8k Row Overflow Error When Updating Row of Size 5k

sql serversql-server-2012update

I'm trying to update a target table which has one row of size 5k to a row of size 5k also.

Since it's one row it's easy to know the row actual size:

select *
from sys.dm_db_index_physical_stats(DB_ID('RODS_HSD_ES'), 
OBJECT_ID(N'TBL_BM_HSD_SUBJECT_AN_148_REPRO'), NULL, NULL, 'DETAILED')

Reproduce

Table wasn't altered since creation. don't see any reason why it should fail. Ideas?

Best Answer

The problem is related to the fact you are updating the clustering key, and the destination table happens to have a partitioning scheme1. When SQL Server is requested to update any component of the clustering key, it must perform an UPDATE and DELETE, or a hybrid update where some of the rows are updated in-place, and some are not.

If you remove the clustered index from the destination table, you'll see the update works.

The error message, while perhaps a bit misleading, is accurate since the resulting row size during the update exceeds the maximum length.

I suggest you consider changing the structure of the table to:

  • not use VARCHAR(MAX) for all those columns. If you don't actually need 2GB of characters in a single column, why define the column that way? Define the column to be the maximum size that will be realistically encountered.
  • perhaps split this table into several tables where the resulting maximum row size is less than 8060 bytes. It seems you have several logical clusters of columns, such as the V_MAX_xxx, V_64_xxx, and V_512_xxx columns, etc.

To simplify your repro, you may want to eliminate the cursor, and only do the following DML operation:

UPDATE dbo.TBL_BM_HSD_SUBJECT_AN_148_REPRO_TARGET
SET [sampletime]  = '2015-12-29 01:11:26.687';

The above column is one of the components of the clustering key and also the partitioning key (updating other CI key columns works fine).

With the clustered index in place, you get this error:

Msg 511, Level 16, State 1, Line 1

Cannot create a row of size 8287 which is greater than the allowable maximum row size of 8060.

The statement has been terminated.

Without the clustered index in place, the statement succeeds.


1 Interestingly, if we eliminate the partitioning from the repro, we find the update succeeds, even with the clustered index in place.