【问题标题】:Oracle Database - Character SetOracle 数据库 - 字符集
【发布时间】:2018-02-13 21:56:58
【问题描述】:

当我使用 sqlplus 或任何其他工具编译时,如何将特殊字符保留在我的包中?

NLS_CHARACTERSET : WE8MSWIN1252
客户角色的设置:未知
问题是:数据表示
操作系统和数据库:UNIX \ Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production

Oracle Database 12c 企业版版本 12.1.0.2.0 - 64 位生产
PL/SQL 版本 12.1.0.2.0 - 生产
核心 12.1.0.2.0 生产
适用于 Linux 的 TNS:版本 12.1.0.2.0 - 生产
NLSRTL 版本 12.1.0.2.0 - 生产

例子:

CREATE OR REPLACE PACKAGE BODY pkg1
AS
  procedure sp 
  IS
  v_var VARCHAR2(100);
  BEGIN
        v_var := '**último**';
  END;

   END;

当我描述包裹时,看起来像这样:

CREATE OR REPLACE PACKAGE BODY HR.pkg1
AS
  procedure sp
  IS
  v_var VARCHAR2(100);
  BEGIN
        v_var := '**£ltimo**';     
  END;


   END;

【问题讨论】:

  • 那么问题真的是“客户角色的设定:未知”吗?您不知道 NLS_LANG 设置或操作系统字符集,还是两者都知道?数据字典中的字符串是否正确(转储它会告诉您)并且仅显示不正确 - 您似乎建议但您是如何建立它的?

标签: plsql character-encoding character oracle12c database-administration


【解决方案1】:

有一种通用方法可以将任意 unicode 数据输入到 oracle 数据库中,将自己限制为 ascii 字符集:

  1. 将目标文本的 utf-8 表示形式确定为十六进制字节序列。

    使用支持 utf8 的编辑器并输入您希望传输到数据库的文本。许多编辑器带有十六进制模式,允许您检查 utf8 表示并将其写在其他地方。或者使用专用的十六进制编辑器或使用 cli 工具(如 od (linux))将文件内容生成为以十六进制表示的八位字节的列表序列:

     od --output-duplicates --format x1 --width=16 demo.txt
    

    输出需要一些后处理来去除行号和空白,但是,这应该很简单。对于批量数据,请使用 sed 或类似工具。

  2. 将十六进制字符串转换为 oracle 的 raw 数据类型。

    在 PlSql 中调用 HEXTORAW(x) 可以解决问题。

  3. raw数据转换为varchar2,即。数据库字符集。

    使用 plsql 包过程utl_i18n.raw_to_char。它的第二个参数指定源编码。

总而言之,该方法归结为类似于(测试字符串是小写字母 af 后跟德语变音符号)的查询:

 select utl_i18n.raw_to_char ( hextoraw ( '616263646566c3a4c3b6c3bcc384c396c39cc39f' ), 'AL32UTF8' ) from dual;

在你的包中你会写:

 v_var := '**' || utl_i18n.raw_to_char ( hextoraw ( 'c3ba' ), 'AL32UTF8' )
               || 'ltimo**';
   -- c3ba being the utf8 encoding of unicode codepoint U+00fa,
   -- 'LATIN SMALL LETTER U WITH ACUTE'

显然,该技术仅在数据库字符集能够首先表示字符时才有效。

快捷方式

  1. 您可以使用任何其他源编码,只要数据库知道该编码,您需要的特殊字符就可以表示。即,可以使用用于拉丁字母的 iso 8859-x 系列编码。对于ú 和 iso8859-1:

     v_var := utl_i18n.raw_to_char ( hextoraw ( 'fa' ), 'WE8ISO8859P1' ) from dual;
    
  2. 在您的数据库中使用国家字符集,您可以通过文字字符串中的代码点输入 unicode 字符。只需使用 UNISTR 函数包装文字字符串:

    v_var := TO_CHAR(UNISTR('**\00faltimo**')) from dual;
    

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多