问题 SQL Server 2012中具有varchar(max)字段的最大行大小


我创建了一个列类型为的表 nvarchar(max)我的理解是他们可以支持2GB。但是在插入时,我仍然收到此错误:

无法创建大小为8061的行,该行大于允许的最大行大小8060。

是否需要对数据库进行全局设置,还是有其他限制?数量是否有限制 varchar(max) 每桌的字段?


12544
2017-10-08 14:48


起源

向我们展示您执行的实际SQL代码。表定义也非常有用。 - RBarryYoung
多少 [n]varchar(max) 你有专栏吗?即使实际数据存储在行外,行本身仍然需要指向它的指针,因此如果要为数百个可变宽度列插入值,则只能在指针上用尽空间。此外,有时由于丢失/改变的固定宽度列仍然消耗空间而产生此错误。 - Martin Smith
有几百列。我没有任何数据,第一次插入失败。 - taylormade201
@MartinSmith我认为你对指针有所了解。如果我使用varchar(max)而不是nvarchar(max)创建表,它似乎工作正常。谢谢 - taylormade201
根本没有代码:没有表定义,没有插入语句。 - Evgeni Nabokov


答案:


SQL Server使用页面来存储数据。页面大小为8kb。 

因此SQL Server中的记录大小(行大小)不能大于8060字节。 

如果数据未安装在8060字节中,则使用参考指针。 当varchar,nvarchar,varbinary,sql_variant或CLR用户定义类型列的组合超出此限制时,SQL Server数据库引擎将具有最大宽度的记录列移动到ROW_OVERFLOW_DATA分配单元中的另一个页面,同时保持 24字节指针 在原始页面上。

将大型记录移动到另一个页面会动态发生,因为记录会根据更新操作延长。缩短记录的更新操作可能会导致记录移回IN_ROW_DATA分配单元中的原始页面。

此外,查询和执行其他选择操作(例如对包含行溢出数据的大型记录进行排序或连接)会减慢处理时间,因为这些记录是同步处理的,而不是异步处理的。

表的记录大小限制 使用稀疏列是8,018字节。当转换的数据加上现有记录数据超过8,018字节时,将返回MSSQLSERVER ERROR 576。在稀疏类型和非稀疏类型之间转换列时,数据库引擎会保留当前记录数据的副本。这会暂时使记录所需的存储空间翻倍。 。

要获取有关可能包含行溢出数据的表或索引的信息,请使用sys.dm_db_index_physical_stats动态管理功能。


8
2018-01-02 10:05





从SQL Server文档:

各列的长度仍必须在限制范围内   8,000个字节 for varchar,nvarchar,varbinary,sql_variant和CLR   用户定义的类型列。 只有他们的组合长度可以超过   表的8,060字节行限制。

其他数据类型列的总和,包括char和nchar数据,    必须落在8,060字节的行限制内。大对象数据也是   免除8,060字节的行限制。

更多信息: https://technet.microsoft.com/en-us/library/ms186981%28v=sql.105%29.aspx


3
2018-02-17 15:56





这来自StackOverflow上的早期线程,可以在这里找到:

无法创建大小为8937的行,其大于允许的最大值8060

导致该错误是因为您不能在SQL服务器中有一行大于8KB(1页的大小),因为不允许行跨页 - 这是SQL Server的基本限制[...]

请注意,SQL Server将允许您创建表,但是如果您尝试实际插入跨越多个页面的任何数据,那么它将给出上述错误。   当然这并没有完全相加,因为如果以上是全部真相,那么单个VARCHAR(8000)列将填充表中的一行! (过去曾经是这种情况)。 SQL Server 2005通过允许来自行的某些数据存储在另一个页面中而改为保留24位指针来克服此限制。

我建议将您的表规范化为一个或多个重新关联的表。


0
2017-10-08 17:10