had*_*aco 2 sql oracle oracle11g
我正在使用带有PL/SQL的Oracle数据库11g.程序是用C#,.NET 4编写的.
我有一个包含varchar(4000)列的表,我想在DB中存储一个泰语文本.我发现当我尝试以泰语存储文本时,其长度超过1333,Oracle抛出异常,尽管最大长度为4000:
ORA-01461:只能将LONG值绑定到LONG列中
我还注意到,当我使用较小的限制时,它按预期工作.ie:varchar(10) - 允许长度为10和更长的文本的值抛出异常:
ORA-01401 插入的值对于列太大
从我已经做过的测试中我可以假设从一个'X'oracle中停止计算实际字母的长度.相反,它乘以最长字母长度值中的字母数(泰语中最长字母的长度为3 - 意味着它就像3个字符),所以1333*3 = 3999,我只能添加另一个字符(用类似的语言)英语).
我的问题:
重要说明:因为我需要支持一个非常大且功能正常的系统,所以我无法将数据类型切换到俱乐部,但它可以解决问题.
谢谢你的帮助.
编辑
我计算这1333个字符的字节数.它们的字节长度是2666,仍然小于4000.我知道最大长度是以字节为单位但我不明白为什么我得到上面的例外.我用过:System.Text.ASCIIEncoding.Unicode.GetByteCount(text)检查字节数.
在描述VARCHAR时,您应该提供一个单位,例如VARCHAR2(200 BYTE)或VARCHAR2(200 CHAR).如果省略该单元,则默认为BYTE(参见Oracle数据库概念,Oracle数据类型一章).这似乎是一个小细节,但是当你有多字节字符集时会变得非常严重.
遗憾的是,VARCHAR2列的最大大小存在硬性限制.它是4000个BYTE(!)(参见Oracle数据库参考,Oracle数据类型一章),最高可达Oracle 11g和.这是一个硬限制,没有办法解决这个问题.唯一的解决方法是CLOB列.
Oracle 12c的情况有所不同.在那里,您可以使用该参数MAX_STRING_SIZE = EXTENDED将限制提升至32767 BYTE(请参阅Oracle数据库语言参考,数据类型和Oracle数据库参考一章,初始化参数一章).所以显而易见的解决方案是:升级到Oracle 12c,MAX_STRING_SIZE = EXTENDED 根据文档设置并更改表定义.在更改表时可能会丢失一些索引,因为之前到12c而不是索引不能保存具有超过4000个BYTE的VARCHAR2值,并且可能仍然存在一些限制.(我必须检查索引的问题,以及是否可以通过重建索引来修复).
您可以尝试更改本机数据库编码(数据库将CHAR映射到BYTE的方式).为此,您通常必须创建一个新数据库并为NLS_CHARACTERSET提供适当的参数.这是数据库运行方式的一个非常大的变化,可能有几个副作用.如果您尝试使用不同的编码添加字符,则可能运气不佳(即您无法将它们存储在数据库中).所以我不建议这个解决方案.
通常没有必要在这样的大文本字段上提供任意查询.您可以尝试识别在大文本列上选择的查询,并将它们迁移到CLOB列上的Oracle Text.但这是一个非常大的变化,可能无法使用现有架构或应用程序.您最终可能会遇到一堆"INSTEAD OF"触发器以及一些缺少约束检查(涉及新创建的CLOB列).
您可以尝试将字符串存储为XML列,而不是CLOB.这些的最大尺寸为4GB.它会损害你的性能,你必须提供INSTEAD OF触发器,你可能会失去一些限制,但它可能对你有用.