问题的简短版本:有没有办法计算在Oracle数据库的VARCHAR(n)
列中存储字符串字符所需的字节数?
更长版本:以下Oracle SQL脚本将在第三个语句中失败。它会尝试在VARCHAR(10)
列中插入10个字符;但是,其中一个字符是具有强烈重音的A.
CREATE TABLE TESTTABLE (NAME VARCHAR(10) NULL);
INSERT INTO TESTTABLE (NAME) VALUES ('abcdefghij');
--1 rows inserted.
INSERT INTO TESTTABLE (NAME) VALUES ('ábcdefghij');
--ORA-12899: value too large for column "ACME"."TESTTABLE"."NAME" (actual: 11, maximum: 10)
我的C#应用程序将字符串存储在Oracle数据库中,我不能只将列类型更改为NVARCHAR2(10)
,这将起作用。应用程序应该将任何较大的字符串修剪为10个字符的限制,因此Oracle不会抱怨它的长度。但基于String.Length
的修剪是一种非常天真的策略:它会盲目地将“ábcdefghij”保留为完整的10个CLR字符。
如何检测'á'将占用数据库行中的2个字节,以便在发出{{1}之前将字符串修剪为“ábcdefghi”声明?
编辑:此问题类似于Best way to shorten UTF8 string based on byte length
答案 0 :(得分:5)
Oracle函数length(string)
返回字符数,lengthb(string)
返回字节数。
答案 1 :(得分:4)
这取决于Oracle设置使用的编码。您可以使用相应的System.Text.Encoding
实例将字符串实例转换为字节数组,例如System.Text.Encoding.UTF8
。 (您正在寻找“GetBytes”方法)
答案 2 :(得分:4)
默认情况下,VARCHAR2(10)
分配10个字节的存储空间,根据数据库字符集和数据,这些字节可能等于或不等于10个字符。但是,您可以声明该列,以便它始终存储10个字符。
当您使用可变宽度字符集时,您几乎总是希望使用字符长度语义VARCHAR2(10 CHAR)
来声明该列。然后,无论您是否碰巧有一些字符需要超过1个字节的存储空间,您始终可以存储10个字符。
如果由于某种原因而无法使用字节长度语义声明列,则可以使用LENGTHB
或VSIZE
函数以字节为单位返回字符串的长度。
select lengthb('ábcdefghij'), vsize('ábcdefghij')
from dual;
对于结果的两列,将返回11。
答案 3 :(得分:1)
你可以得到字符串的长度,如下所示:
UTF8Encoding Encoding = new UTF8Encoding();
byte[] UTF8String = Encoding.GetBytes("ábcdefghij");
int StringLenght = UTF8String.Length
事实上,对于你的例子,它返回11。