1

问题的简短版本:VARCHAR(n)有没有一种方法可以计算将字符串的字符存储在 Oracle 数据库的列中需要多少字节?

更长的版本:以下 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 个字节,以便在发出语句之前将字符串修剪为“ábcdefghi”INSERT

编辑:这个问题类似于基于字节长度缩短 UTF8 字符串的最佳方法

4

4 回答 4

5

Oracle 函数length(string)返回字符数,lengthb(string)返回字节数。

于 2013-03-11T20:02:25.273 回答
4

默认情况下,VARCHAR2(10)分配 10 个字节的存储空间,这可能等于也可能不等于 10 个字符,具体取决于数据库字符集和数据。但是,您可以声明该列,使其始终存储 10 个字符。

当您使用可变宽度字符集时,您几乎总是希望使用字符长度语义来声明列VARCHAR2(10 CHAR)。然后,无论您是否碰巧有一些字符需要超过 1 个字节的存储空间,您始终可以存储 10 个字符。

如果由于某种原因您无法使用字节长度语义来声明列,则可以使用LENGTHBorVSIZE函数以字节为单位返回字符串的长度。

select lengthb('ábcdefghij'), vsize('ábcdefghij')
  from dual;

将为结果的两列返回 11。

于 2013-03-11T20:23:18.317 回答
4

这取决于 Oracle 设置使用的编码。您可以使用相应的实例将字符串实例转换为字节数组System.Text.Encoding,例如System.Text.Encoding.UTF8. (您正在寻找“GetBytes”方法)

于 2013-03-11T19:52:13.630 回答
1

您可以像这样获取字符串的字节长度:

UTF8Encoding Encoding = new UTF8Encoding();
byte[] UTF8String = Encoding.GetBytes("ábcdefghij");
int StringLenght = UTF8String.Length

实际上,对于您的示例,它返回 11。

于 2013-03-11T19:57:44.750 回答