SQL*_*DBA 6 sql-server-2005 sql-server
我有一个场景,由于 8060 的最大行大小限制,某些插入/更新失败。对于具有大量 varchar 250 到 500、数字和日期时间列的表,会发生这种情况。我试图在我的测试环境中重现同样的场景,但无法这样做。
你们知道如何在测试环境中重现它吗?任何示例都非常适合解释。
我的环境是SQL server 2005 Ent。版。我的表有 ~470 列。我知道这是一个糟糕的设计,但它不在我的控制范围内。
我在下面尝试过,但它不起作用:
create table test (col1 varchar(5000), col2 varchar(5000))
insert into test values (replicate('A', 5000), replicate('B', 5000))
Run Code Online (Sandbox Code Playgroud)
即使记录长度大于 8060,它也能成功插入。
SQL Server 有每行 8060 字节的限制。请参阅SQL Server 的最大容量规范中的“每行字节数” 。此行的附加信息有以下短语:
SQL Server 支持行溢出存储,它允许将可变长度列推离行。对于从行中推出的可变长度列,主记录中只存储一个 24 字节的根;因此,有效行限制高于以前版本的 SQL Server。有关详细信息,请参阅 SQL Server 联机丛书中的“超过 8 KB 的行溢出数据”主题。
因此,当您varchar在一行中插入两个每 5000 个字节长的值时,它们中的一个或两个将存储在行外并且仅占用 24 个字节而不是 5000+2。
但是,如果varchar表中有 470列,则只能在此类表的同一行中插入8060/24=335非空varchar值。事实上,甚至略小于 335,因为在一行中还有其他结构占用了一些空间。
MSDN:行溢出数据超过 8 KB
因此,要在测试环境中重现它,请创建一个至少包含 336varchar列的表,并尝试在同一行中插入 336 个长度超过 24 个字符的非空值。
这是因为您达到了行大小限制。但这也会影响您的生产服务器吗?
您确定两台服务器相同并且两台服务器使用相同的表设计吗?
你可以尝试用nvarchar(max)(eg)来代替。nvarchar(250)用于测试目的。这将使用更多空间并且速度会更慢,但会避免 8060 的限制。出于测试目的应该没问题。