需求:oracle有个备注长度只有100,但是不能扩大,只能截取java传输过程中的字符长度
如何知道一个汉字在Oracle数据库中具体占用几个字节?
方式一:这个其实和Oracle的配置是相关的,用以下语句查询当前数据库的字符集:
理论
select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';
可以得到如下结果:
如果value=ZHS16GBK,那么一个汉字占用2个字节,
如果value=AL32UTF8,那么一个汉字占用3个字节(这是Oracle数据库默认的)。
实际
所以可以看出我的数据库是占用2个字节
方式二:查看oracle server端字符集
理论
select userenv('language') from dual;
如果结果是下面这样的,一个汉字就占用两个字节
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
如果结果是下面这样的,那么一个汉字就占用三个字节
SIMPLIFIED CHINESE_CHINA.AL32UTF8
实际
方式三:也可以尝试用以下语句查询一个汉字占用的字节长度
理论
直接可以查看对应字符的长度(空格是1个长度)
select lengthb('你') from dual;
实际
java
实现代码
package com.zjnac.restfulapi.util;
import java.io.IOException;
/**
* @ClassName CutStringUtil
* @Description 按字节截取字符串
* @Author Duplicator
* @Date 2019/8/21 14:38
* @Version 1.0
**/
public class CutStringUtil {
public static void main(String[] args) throws IOException {
String str = "ab你好cd谢谢";
int len = str.getBytes("gbk").length;
for (int x = 0; x < len; x++) {
System.out.println("截取" + (x + 1) + "字节结果时:"
+ cutStringByGBK(str, x + 1));
}
String str1 = "ab你好cd杮";
int len1 = str.getBytes("gbk").length;
for (int x = 0; x < len1; x++) {
System.out.println("截取" + (x + 1) + "字节结果时:"
+ cutStringByUTF8(str1, x + 1));
}
}
// 使用UTF-8编码表进行截取字符串,一个汉字对应三个负数,一个英文字符对应一个正数
public static String cutStringByUTF8(String str, int len) throws IOException {
if(str==null){
return null;
}
//前提不知道str他的长度,而指定的len长于实际str长度数组下标超过异常
int actualLen = str.getBytes("gbk").length;
if(actualLen<len){
len = actualLen;
}
byte[] buf = str.getBytes("utf-8");
int count = 0;
for (int x = len - 1; x >= 0; x--) {
if (buf[x] < 0) {
count++;
} else {
break;
}
}
if (count % 3 == 0) {
return new String(buf, 0, len, "utf-8");
} else if (count % 3 == 1) {
return new String(buf, 0, len - 1, "utf-8");
} else {
return new String(buf, 0, len - 2, "utf-8");
}
}
// 使用GBK编码表进行字符串的截取,一个英文字符对应码表一个正数,一个汉字对应两个负数
public static String cutStringByGBK(String str, int len)
throws IOException {
if(str==null){
return null;
}
int actualLen = str.getBytes("gbk").length;
if(actualLen<len){
len = actualLen;
}
byte[] buf = str.getBytes("gbk");
int count = 0;
for (int x = len - 1; x >= 0; x--) {
//统计按字节截取的字符串中,中文字符串有几个字节
//小于0的是中文的部分
if (buf[x] < 0) {
count++;
} else {
break;
}
}
if (count % 2 == 0) {
return new String(buf, 0, len, "gbk");
} else {
return new String(buf, 0, len - 1, "gbk");
}
}
}