调用Oracle PL/SQL存储过程时使用的编码是什么?

9
在我的ColdFusion页面上,我调用了一个PL/SQL过程。HTML表单使用UTF-8编码,Oracle数据库的编码为WE8ISO8859P1。那么在下面的i_value的情况下会发生什么样的转换?
我特别想知道MS Word左引号(在UTF-8中编码为E28098)会发生什么事情。当我在PL/SQL中解码i_value时,它变成了18(十六进制)。考虑到它是U+2018,这就有些合理了,但我仍然想知道为什么20被吞掉了。
<CFSTOREDPROC PROCEDURE = "my_schema.lib.write_field" datasource="#datasource#">
        <cfprocparam cfsqltype="CF_SQL_VARCHAR" variable="i_name"   value="remark"  type="In">
        <cfprocparam cfsqltype="CF_SQL_VARCHAR" variable="i_value" value="#Form.remark#" type="In">
</CFSTOREDPROC>

我不是CF专家,所以没有答案,只有一个评论:每个客户端环境(而您的CF是Oracle DB的客户端)连接到Oracle DB时都使用NLS_LANG环境变量来确定用于Oracle DB连接的客户端字符集。因此,在您的Oracle DB侧设置了一个字符集(WE8ISO8859P1),在您的HTML页面上设置了第二个字符集(UTF8),在您的ColdFusion服务器上预设了第三个字符集,最可能还为您的CF服务器中使用的Oracle客户端设置了第四个字符集。我假设您需要找到该特定选项并将其设置为例如ENGLISH_AMERICA.AL32UTF8。 - peter.hrasko.sk
当然,NLS_LANG变量可以在Oracle DB连接中被替换为某种专用参数。 (如果我没记错的话,ODP.NET就是这样做的。)不过,我的评论仍然适用——你需要找到该DB连接属性并进行设置。 - peter.hrasko.sk
即使知道客户端编码,我仍想了解发生了什么样的转换。我注意到当发送到数据库时,一些字节似乎被吞噬了,例如左单引号(UTF-16中的0x2018)在数据库中变成了0x18。@nop77svk - Roland
啊,这就是你的意思!据我所知,在Oracle中的转换是由${ORACLE_HOME}/nls文件夹中的好文件驱动的。但我无法告诉你具体细节。 - peter.hrasko.sk
从我所给的例子来看,似乎最高有效字节被忽略了,只有最低有效字节被考虑。 - Roland
不过,我也不确定。如果我是你,并且我对所有应用程序层都有完全控制权,我会尝试玩弄 nvarchar2 字符串,并逐个调试每个应用程序层的转换。 - peter.hrasko.sk
1个回答

0

ColdFusion基于Java,因此我猜字符串变量使用UTF-16进行编码。

当从UTF-16(2字节编码)转换为1字节编码(例如WE8ISO8859P1)时,如我的示例所示,MSB将被忽略,只考虑LSB。

这可以解释观察到的行为: 我注意到发送到数据库时,一些字节似乎被吞噬了,例如left single quotation mark(UTF-16中的0x2018)在数据库中变成了0x18。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接