JPR*_*man 5 oracle encoding plsql sqlplus utf-8
我有一个在 Oracle 数据库(Windows 或 Unix 操作系统)上运行的脚本。它提取数据,然后将其假脱机到 .txt 文件。
\n为了确保文件不变,在运行脚本时对数据进行哈希处理,然后在 Web 应用程序中重新计算该哈希值。这可以工作 9/10 次,但有时它会提供不匹配,即使文件是相同的,我将其隔离为编码问题。
\n为了确定文件使用的编码,该脚本将 3 个非 ASCII 字符写入文件,这些字符在不同的编码方案中编码不同。这些稍后会映射到后端。
\n--Encoding related information\nSPOOL &&file_desc/Encoding.txt\nSELECT ('\xe2\x82\xac'||';'||'\xc6\x92'||';'||'\xe2\x80\xb0') FROM sys.dual;\nSPOOL off\nRun Code Online (Sandbox Code Playgroud)\n在使用 UTF-8 编码的数据库上,应正确假脱机包含 NONASCII 字符的数据,并且 3 个 NONASCII 字符也应正确假脱机。
\n当使用 .AL32UTF8 系统字符集(与 DB 相同)时,数据会正确假脱机,但用于编码的 3 个字符则不然。这使得我无法确定使用了哪种编码方案。
\n数据库具有以下字符集(从database_properties获得):
\nNLS_CHARACTESET:AL32UTF8
\nNLS_NCHAR_CHARACTERSET:AL16UTF16
\n使用 SQL-Developer 时(将编码设置为 UTF8 后)),我没有任何问题。日语和希腊字符都正确显示,并且用于编码的字符也正确显示,从而在稍后重新计算时导致成功的哈希匹配。
\n我也需要它在 SQL*Plus 中工作,但我\xe2\x80\x99 遇到了问题。我\xe2\x80\x99已经尝试了一系列不同的变体。DB是Oracle 18c Express版本:
\n仅将字符代码页设置为 utf-8,对应于 DB\nchcp 65001(utf-8 的代码) NLS_LANG 字符集:.WE8MSWIN1252\n表名包含日语字符的文件给出\nan 编码 \xe2\x80\x98error\xe2\ x80\x99: JAPANESE\xc2\xbf 用于\n确定编码的 3 个字符的文件运行良好:\xe2\x82\xac;\xc6\x92;\xe2\x80\xb0
\n代码页没有更改,但更新了 NLS_LANG 字符集\nNLS_LANG 字符集:.AL32UTF8 表名包含日语字符的文件现在显示正常:JAPANESE\xe4\xb8\x96 用于确定编码的包含 3\n字符的文件现在是突然 \xe2\x80\x98empty\xe2\x80\x99 然而:;;
\n将 NLS_LANG 设置为与 DB 相同并更新代码页 chcp\n65001(utf-8 的代码) NLS_LANG 字符集:.AL32UTF8 包含日语字符的表名的文件现在显示正常:\nJAPANESE\xe4\xb8\x96 带有的文件用于确定编码的 3 个字符现在突然变为 \xe2\x80\x98empty\xe2\x80\x99 然而:;;
\n将 NLS_LANG 设置为 NLS_NCHAR_Characterset。以防万一,我还\n尝试将系统字符集设置为 AL16UTF16,它等于\nNLS_NCHAR_Characterset,认为这可能有助于解决问题,\n但随后出现以下错误:错误 19 初始化 SQL*PLUS\n无效的 NLS 字符集对于这个操作系统环境
\n代码页并不重要,因为它只关心输出到命令窗口。
\n正如所料,当使用 WE8MSWIN1252 时,非 ASCII 字符的假脱机不起作用,因为它不识别这些字符。
\n然而,当使用 AL32UTF8 时, sys.dual 形式的 3 个非 ASCII 字符的假脱机不再起作用,即使它确实知道这些字符。
\n我花了几天时间来解决这个问题,我不知道为什么会出现这种情况,有人可以帮助我吗?
\n*编辑,kfinity 提供了解决方案,尽管不能 100% 确定为什么会出现这种情况。那么如果有人知道吗?
\n如果我们将 select 语句替换为以下内容,它确实有效:
\nselect unistr('\\20AC;\\0192;\\2030') from dual;\nRun Code Online (Sandbox Code Playgroud)\n
我不太确定问题是什么,但如果您尝试这样做:
select unistr('\20AC;\0192;\2030') from dual;
Run Code Online (Sandbox Code Playgroud)
我认为这会绕过让 SQL*Plus 从 .sql 文件中读取正确字符值的问题。