You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle NVARCHAR2字段插入中文:JDBC拼接SQL编码适配咨询

解决GBK编码Java应用向WE8MSWIN1252编码Oracle的NVARCHAR2字段拼接SQL插入中文的问题

咱先把问题根源捋明白:你的Java应用是GBK编码,直接拼接SQL传中文时,JDBC驱动会把GBK字节按Oracle的WE8MSWIN1252编码解析——但WE8MSWIN1252根本不支持中文字符,自然就乱码了。而setNString和PLSQL的N'测试'都是直接传递Unicode格式的字符,刚好匹配NVARCHAR2的Unicode存储特性,所以没问题。

如果因为某些限制必须用SQL拼接方式,这儿给你两个可行的编码转换方案,但必须先强调:SQL拼接存在严重的SQL注入风险,除非是完全可控的输入,否则优先用PreparedStatement的setNString!

方案一:模拟PLSQL的N前缀格式,转Unicode编码拼接

把GBK字符串转成Unicode转义格式(类似\u6d4b\u8bd5),然后用N'...'包裹后拼接SQL,让Oracle直接识别为Unicode字符:

String gbkValue = "测试";
StringBuilder unicodeBuilder = new StringBuilder();
// 遍历每个字符,转成4位十六进制的Unicode转义符
for (char c : gbkValue.toCharArray()) {
    unicodeBuilder.append("\\u")
                  .append(String.format("%04x", (int) c));
}
// 拼接SQL时用N前缀包裹转义后的字符串
String sql = "UPDATE TEST_TEST t SET t.val = N'" + unicodeBuilder.toString() + "' WHERE t.id = '1'";

方案二:利用Oracle的UNISTR函数转换

UNISTR函数可以直接解析Unicode转义字符串,效果和N前缀类似,代码逻辑和方案一差不多,只是拼接方式不同:

String gbkValue = "测试";
StringBuilder unicodeBuilder = new StringBuilder();
for (char c : gbkValue.toCharArray()) {
    unicodeBuilder.append("\\u")
                  .append(String.format("%04x", (int) c));
}
// 使用UNISTR函数处理转义字符串
String sql = "UPDATE TEST_TEST t SET t.val = UNISTR('" + unicodeBuilder.toString() + "') WHERE t.id = '1'";

关键提醒

  1. 这两种方案都只能处理纯中文或已知字符集的字符串,若包含特殊字符(比如单引号),必须额外做转义处理,否则会导致SQL语法错误或注入风险。
  2. 再次强烈建议:能不用SQL拼接就不用,PreparedStatement的setNString不仅能彻底解决编码问题,还能从根源避免SQL注入,是最优解。

内容的提问来源于stack exchange,提问作者huangzhtao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:22:04