SQL Server 超过了每行的最大字节数(8060)的原因和解决办法(转)

本文介绍在使用SQL Server时遇到的行大小超出每行最大字节数8060的问题,包括现象、原因及两种解决方案:调整列定义以符合限制或忽略警告继续使用。

原地址:http://limindo.blog.163.com/blog/static/264758562009101110485410/


一、现象
     一般出现这种现象都是适用sql文件在查询分析器里建库的时候,现象一般都是提示:

"警告: 已创建表 'XXXX,但其最大行大小(89960)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。"

已创建表 'xxxx',但其最大行大小(10438)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。      其中

xxxx是你的建的表名,10438是你建表语句中可变长度列(如 nvarchar 或 varbinary)的总长度,8060是SQL Server对行长度的最大限制。


二、原因
    其实把上面三个概念搞清楚,警告的原因就应该清楚了,就是因为你的建表语句中可变长度列的总长度超过了SQL Server对行最大长度的限制8060。如果每一行中数据

的总长度不超过8060 字节,就仍可以向表中插入行。但是如果数据超过8060 字节,因此系统提示你就会出现插入或更新操作失败。
    错误提示:
服务器:信息 511,级别 16,状态 1,第 5 行
无法创建大小为 的行,该值大于允许的最大值 8060。
语句已终止。      举个例子:比如我总共有10块钱,买A东西可能花1-5块,买B东西可能花2-3块,买C东西可能花3-6块,那我在做预算的时候就要提醒自己,如果ABC三个

东西都要花上限的钱,那我的钱可就不够了,因为5+3+6=14 >10,虽然可能我只花了1+2+3=6块钱就把ABC全买了

 

三、解决
    知道问题的原因了,解决办法相对就简单了!
    1、修改你建表语句中相应的列的数据类型或长度(如将nvarchar格式改成text),让可变长度列的加和小于8060。这样可以彻底避免出现上述错误发生,当然上述的错

误并不是必然出现。
    2、在绝大多数情况下不会出现各列长度超过行限制的时候(这个需要根据存储的数据的情况自行判断),你也可以忽略这个提示,这并不会必然影响到你正常的操作。

 

<think>我们面对的问题是在SAP BusinessOne中更新字段时,由于SQLServer数据长度超过8060字节限制而报错。SQLServer对于单数据有8060字节的限制(对于数据页大小8KB的情况),当一数据的总大小超过这个限制时,就会发生错误。解决方案思路:1.分析结构,找出导致大小过大的列(可能是某些列的长度设置过大,或者列数过多)。2.考虑将大列移动到单独的(即垂直分割),使用外键关联。3.使用溢出(ROW_OVERFLOW)存储,SQLServer2005及以后版本支持将varchar、nvarchar、varbinary等大列存储在单独的数据页中,但注意这有性能影响。4.压缩数据:使用SQLServer的数据压缩功能(压缩或页压缩)来减少大小。5.重新设计结构,例如将大列拆分成多个,或者将大列的数据存储在文件系统中,数据库中只存储文件路径。具体步骤:1. **分析结构**:使用以下SQL查询来检查中各列的长度大小:```sqlSELECTCOL_NAME(object_id,column_id) ASColumnName,system_type_id,max_lengthFROMsys.columnsWHERE object_id =OBJECT_ID('YourTableName');```同时,计算所有列的最大长度之,看是否超过8060字节。2.**使用溢出存储**:对于可变长度列(如varchar,nvarchar,varbinary),如果一中的数据超过8060字节SQLServer会自动将部分列移动到ROW_OVERFLOW_DATA分配单元中。但要注意:-该列必须是可变长度。-中所有固定长度列的大小加上可变长度列的开销(如长度指针等)不能超过8060字节。因此,如果中有很多固定长度列,或者可变长度列的实际长度很大,可能导致问题。3.**垂直分割**:将一些大列移动到另一个中,原通过主键关联。例如:```sql--原CREATETABLE MainTable (IDINT PRIMARYKEY,Column1 INT,Column2VARCHAR(100),...--其他列,但避免超过8060);--新,存放大列CREATETABLE OverflowTable (IDINT PRIMARYKEY,LargeColumn1VARCHAR(MAX),LargeColumn2NVARCHAR(MAX),FOREIGN KEY(ID) REFERENCESMainTable(ID));```这样,更新操作时,如果只是更新主的列,就不会触及大列。4.**使用数据压缩**:SQLServer提供了压缩页压缩,可以减小大小压缩通过改变数据的存储格式来减小大小(例如,使用可变长度存储类型)。启用压缩:```sqlALTERTABLE YourTable REBUILDWITH (DATA_COMPRESSION= ROW);--或 PAGE```注意:压缩需要额外的CPU资源,且并非所有版本都支持(需要企业版或开发版)。5. **将大列改为LOB类型**:将大列的数据类型改为VARCHAR(MAX)、NVARCHAR(MAX)或VARBINARY(MAX)。这些类型的数据默认存储在外(除非数据很小,小于8000字节且指定了内存储)。这样,这些列就不会计入8060字节的限制。但是,在查询这些列时可能会有性能损失。6.**减少列的大小**:如果可能,检查业务逻辑是否真的需要那么大的列,是否可以减小列的长度。7. **使用文件存储**:将大文本或二进制数据存储在文件系统中,数据库中只存储文件路径。在SAPBusiness One中实施这些解决方案需要注意: -SAP BusinessOne的数据库结构是固定的,直接修改结构可能不被支持,且会影响系统稳定性。因此,在修改前必须咨询SAP支持或合作伙伴。-对于自定义字段(UserDefinedFields,UDF)或自定义,我们可能有更大的灵活性。根据引用[2]提到的SAP帮助文档,当列的长度不足时,ABAP会显示星号提示溢出。这里的问题类似,但发生在数据库层面。由于SAPBusiness One是基于SQLServer的,因此上述解决方案在技术上是可的。但是,必须谨慎操作,避免破坏系统完整性。推荐步骤:1.首先确定是哪个在更新时出错。通过错误消息或日志可以定位。2.分析该大小,找出导致大小过大的列。3.如果是自定义字段,可以考虑将自定义字段的数据类型改为大对象类型(如NVARCHAR(MAX)),或者将多个自定义字段拆分成多个(但需要修改自定义程序)。4.如果是标准,则需要联系SAP支持,看是否有官方解决方案(如补丁或修改配置)。引用[1]提到SAP说明2629103,虽然与SQL跟踪相关,但说明SAP会提供一些配置参数来调整,因此类似地,可能有针对此问题的SAP说明。另外,引用[3]提到SAP应用程序与Kafka集成,但这与当前问题关系不大。因此,建议用户: -检查结构,特别是那些长度很大的列。 -如果是自定义字段,尝试修改自定义字段为LOB类型。-联系SAP支持,获取官方建议。如果用户有进一步的问题,可以提供具体的结构信息。相关问题:1.如何检查SQL Server大小?2.在SAP BusinessOne中修改自定义字段的数据类型有哪些注意事项?3. SQLServer溢出存储机制是怎样的?4.SAP BusinessOne支持哪些SQLServer的数据压缩技术?5.垂直分割在SAP BusinessOne中如何实现?</think>### SAP Business One 更新字段时 SQL Server 报错 "大小超过 8060 字节" 解决方案 #### 问题原因 SQL Server 对单数据有 **8060 字节的硬性限制**(数据页大小 8KB)。当 SAP Business One 尝试更新包含大量字段或大尺寸字段(如长文本、二进制数据)的记录时,若整数据总长度超过此限制,即触发错误。常见场景包括: - 包含过多 `VARCHAR`/`NVARCHAR` 字段 - 存在大型自定义字段(UDF) - 字段更新后导致总长度膨胀 --- ### 解决方案(按优先级排序) #### 1. **优化结构**(推荐) **原理**:将大字段移出存储区,避免计入 8060 字节限制。 - **步骤**: 1. 定位大字段(如 `NVARCHAR(4000)`): ```sql SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'YourTable' AND DATA_TYPE LIKE '%CHAR%' ``` 2. 修改大字段为 `VARCHAR(MAX)` 或 `NVARCHAR(MAX)` 类型(存储到 LOB 页): ```sql ALTER TABLE YourTable ALTER COLUMN LargeField NVARCHAR(MAX) ``` 3. 若需强制外存储(可选): ```sql EXEC sp_tableoption 'YourTable', 'large value types out of row', 1 ``` **效果**:`MAX` 类型字段仅占用内 24 字节指针[^1]。 #### 2. **启用数据压缩** **原理**:通过压缩减少实际存储大小。 - **步骤**: 1. 评估压缩可性(需 SQL Server Enterprise 版): ```sql EXEC sp_estimate_data_compression_savings 'dbo', 'YourTable', NULL, NULL, 'ROW' ``` 2. 启用压缩: ```sql ALTER TABLE YourTable REBUILD WITH (DATA_COMPRESSION = ROW) ``` **注意**:压缩后仍需保证**未压缩的元数据长度** ≤ 8060 字节[^2]。 #### 3. **垂直拆分** **原理**:将大字段拆分到关联。 - **步骤**: 1. 创建存储大字段: ```sql CREATE TABLE YourTable_Overflow ( KeyField INT PRIMARY KEY, LargeField NVARCHAR(MAX), FOREIGN KEY (KeyField) REFERENCES YourTable(PrimaryKey) ) ``` 2. 迁移数据并删除原大字段: ```sql INSERT INTO YourTable_Overflow (KeyField, LargeField) SELECT PrimaryKey, LargeField FROM YourTable ALTER TABLE YourTable DROP COLUMN LargeField ``` **适用场景**:标准无法修改时(需通过 SAP B1 SDK 调整逻辑)。 #### 4. **清理冗余数据** - 缩短超长字段值(如截断日志文本) - 删除未使用的旧字段 - 检查自定义字段(UDF)是否必要 --- ### SAP Business One 特定建议 1. **自定义字段管理**: - 避免创建过多长文本 UDF(优先用 `NVARCHAR(MAX)`) - 通过 `管理 → 系统初始化 → 自定义工具 → 用户字段` 修改字段类型 2. **补丁更新**: - 检查 SAP Note **2629103** 等更新(可能含优化)[^1] 3. **事务拆分**: - 将单次大更新拆分为多次小事务(如分批更新字段) --- ### 预防措施 - **设计阶段**:预估长度(固定长度字段 + 可变字段最大长度 ≤ 8060) - **监控**:定期检查大小: ```sql EXEC sp_spaceused 'YourTable' ``` - **测试环境**:模拟大容量数据更新验证稳定性 > ⚠️ **重要警告**:修改 SAP 标准结构需通过官方支持渠道(SAP OSS),否则可能导致系统不稳定。自定义可灵活调整。 --- ### 相关问题 1. 如何快速定位 SAP Business One 中占用空间最大? 2. SQL Server 的 `VARCHAR(MAX)` `NVARCHAR(MAX)` 在性能上有何差异? 3. SAP Business One 自定义字段的最佳实践是什么? 4. 除了大小限制,SQL Server 还有哪些常见存储瓶颈? 5. 如何通过 SAP B1 SDK 安全地修改结构? [^1]: SQL Server 物理结构限制,参考 [Microsoft Docs](https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server) [^2]: SAP 数据溢出处理机制,参考 [SAP Help](https://help.sap.com/doc/saphelp_nw74/7.4.16/en-us/4e/56898907564f49e10000000a42189e/frameset.htm)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值