【问题标题】:Handle special characters during textfile import into OracleDB via Apex在通过 Apex 将文本文件导入 Oracle DB 期间处理特殊字符
【发布时间】:2016-04-08 09:02:40
【问题描述】:

我正在开发一种将文本文件导入 BLOB 列 (OracleDB) 的工具。这是通过带有文件浏览按钮和连接的导入程序的 Apex 页面处理的。

有关导入 BLOB 过程的更多详细信息:http://ittichaicham.com/2011/03/file-browser-in-apex-4-with-blob-column-specified-in-item-source-attribute/

我使用的文本文件包含特殊字符、空值、小数分隔符等。例如:

(...) 111888|Overflakkée, Blabla|罗纳河的街道名||12-13|UXC 地名 (...)

由于都是字符数据,我用这个过程将 BLOB 转换为 CLOB:

FUNCTION blob_to_clob (blob_in IN BLOB)
RETURN CLOB
AS
v_clob CLOB;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);

FOR i IN 1..CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer)
LOOP

   v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));

DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
v_start := v_start + v_buffer;
END LOOP;
RETURN v_clob;
END blob_to_clob;

查看更多信息:http://www.dba-oracle.com/t_convert_blob_to_clob_script.htm

问题: 在将 blob 转换为 clob 时,一些特殊字符会丢失/更改。

例如这一行:

(...) 111888|Overflakkée, Blabla|罗纳河的街道名||12-13|UXC 地名 (...)

将变成这一行:

(...) 111888|Overflakk. Blabla|Rh 的街道名称|12-13|UXC 地名 (...)

行长、字符甚至分隔符(在本例中为“|”)都已更改/不可见。

  • 有没有办法获取丢失的字符 + 保留分隔符/空值? (如果需要将 'é' 更改为 'e' 也可以)。
  • 有没有更有效的方法将文本文件导入 BLOB/CLOB 列?

问候

【问题讨论】:

  • 为了缩小问题范围,您是否尝试将文件直接导入数据库(不使用 APEX)并查看结果如何?在我看来,它更像是语言设置
  • 尝试使用 UTF-8 编码保存文件,然后上传文件。为此,使用记事本打开文件>另存为>在窗口的下部选择 UTF-8 作为编码。
  • 确实@Christian_l,使用 UTF-8 编码导入文件正在工作。但是,仍然丢失了一些字符:“Privée”将变为“Prive”,因此删除了特殊字符。这可能是解决方案,但需要以 UTF-8 格式提供文件。这是可行的。 - 有人知道一种将所有传入文件自动转换为 UTF-8 格式的方法吗,无论它们最初是什么格式?

标签: regex blob special-characters oracle-apex file-import


【解决方案1】:

你需要做一个从源字符集到数据库字符集的转换

这是我做的一个例子(主要是为了获取大的json对象,javascript是utf8,在8859p1数据库中使用),很简单,我就不多解释了。

转换的示例用法:

l_clob := blob_to_clob (l_blob, '1');

功能:

function blob_to_clob (blob_in in blob, p_convertutf8 in char default 0)
   return clob as
   /* Ólafur Tryggvason */
   l_clob           clob;
   l_varchar        varchar2 (32767);
   l_start          pls_integer := 1;
   l_buffer         pls_integer := 32767;
   l_characterset   nls_database_parameters.value%type;
begin
   select value
     into l_characterset
     from nls_database_parameters
    where parameter = 'NLS_CHARACTERSET';

   dbms_lob.createtemporary (l_clob, true);

   for i in 1 .. ceil (dbms_lob.getlength (blob_in) / l_buffer) loop
      l_varchar := utl_raw.cast_to_varchar2 (dbms_lob.substr (blob_in, l_buffer, l_start));

      if p_convertutf8 = '1' then
         l_varchar := convert (l_varchar, l_characterset, 'UTF8'); -- WE8ISO8859P1
      end if;

      dbms_lob.writeappend (l_clob, length (l_varchar), l_varchar);

      l_start := l_start + l_buffer;
   end loop;

   return l_clob;
end blob_to_clob;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-21
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2018-05-22
    相关资源
    最近更新 更多