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')
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
andDELETE
, 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:
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.V_MAX_xxx
,V_64_xxx
, andV_512_xxx
columns, etc.To simplify your repro, you may want to eliminate the cursor, and only do the following DML operation:
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:
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.