我有一个NLS_CHARACTERSET=AL32UTF8的数据库。
使用JDBC和Oracle瘦驱动程序,以及一个带有绑定参数的准备好的语句,我将UTF-16 java字符串"\uD83D\uDE33"写入VARCHAR2字段。
使用SQLPLUS并选择utl_raw.cast_to_raw字段,我可以看到以下原始值:EFBFBD20EDB8B3,即:"\uFFFD\uDE33"
当我使用JDBC将字段读回UTF-16java字符串时,unicode值将转换为替换字符,即:"\uFFFD\uFFFD"。
如何重新获得原始Unicode字符串?
因为我读回的是"\FFFD\FFFD",如果我在where条件中使用这个值,它将永远不会与数据库中的值匹配。
问题似乎是Oracle JDBC精简驱动程序如何处理单个代理代码单元。在数据库中,它最终存储了一个代理代码单元,而不是用替换字符替换它。但当字段被读取时,is会用替换字符替换单个代理代码单元。因此,写入的内容、存储的内容和检索的内容都是不同的。
我所期望的是,存储在数据库中的内容就是读回的内容。因此,当存储无效的UTF-16字符串时,它应该存储单个代理作为替换字符,而不是单个代理代码单元。这样,我就可以在后续查询的where条件中使用任何读回的值。