我们在数据库中的表上收到此错误:
Cannot create a row of size 8937 which is greater than the allowable maximum of 8060.
该表由大约 400 个 varchar(max)
组成字段。但是,我们仅将空字符串插入到这些字段中。
插入似乎有效,但是当使用 SqlXml
时读取数据或运行时DBCC DBREINDEX
在表的主键上,出现错误。
它仅发生在一个特定的 SQL Server (2005) 上,而不发生在其他 SQL Server (2005 Express) 上。有问题的机器运行 64 位 Windows,其他机器运行 32 位 Windows。
有人对此有任何想法吗?如果我需要提供更多信息,请告诉我。
我想指出的是,我完全同意尝试使用这么多 varchar(max) 列是相当极端、不寻常的,而且根本不明智。这是有原因的,主要是不受我控制的,我不会在这里讨论。
最佳答案
导致该错误的原因是 SQL Server 中不能有大于 8KB(1 页大小)的行,因为行不允许跨页 - 这是 SQL Server 的基本限制,您可以阅读更多有关在这里:
请注意,SQL Server 将允许您创建表,但是如果您尝试实际插入跨多个页面的任何数据,则会出现上述错误。
当然,这不太合理,因为如果以上是全部事实,那么单个 VARCHAR(8000)
列将填充表中的一行! (过去就是这样)。 SQL Server 2005 允许将行中的某些数据存储在另一个页中,而不是保留 24 字节指针,从而绕过了这一限制。您可以在这里阅读相关内容:
- How Sql Server 2005 bypasses the 8KB row size limitation
- Maximum Row Size in SQL Server 2005 to the Limit
正如您现在所看到的,这意味着行现在可以跨越多个页面,但是单列行仍然需要适合单个页面(因此列的最大大小为 VARCHAR(8000)
)并且您可以拥有的此类列的总数仍然有限制(根据我的估计,大约 8000/24 = ~300)
当然,这都忽略了要点,即单个表上有 400 宽列是荒谬的!!!
您应该仔细检查您的数据库架构,并提出一些更合理的方案 - 您可以从选择一些对列大小更保守的估计开始(例如 VARCHAR(255)
或 VARCHAR(50)
),但您确实需要将其中一些字段拆分到单独的表中。
关于sql-server - 无法创建大小为 8937 的行,该行大于允许的最大值 8060,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3905934/