【问题标题】:Removing replacement character � from column从列中删除替换字符 �
【发布时间】:2017-02-24 23:03:58
【问题描述】:

根据我目前的研究,这个字符表示数据库和前端之间的编码错误。不幸的是,我无法控制其中任何一个。我正在使用 Teradata Studio。

如何过滤掉这个字符?我正在尝试对偶尔包含 的列执行REGEX_SUBSTR 函数,这会引发错误“字符串包含不可翻译的字符”。

这是我的 SQL。 AIRCFT_POSITN_ID 是包含替换字符的列。

 SELECT DISTINCT AIRCFT_POSITN_ID, 
 REGEXP_SUBSTR(AIRCFT_POSITN_ID, '[0-9]+') AS AUTOROW
 FROM PROD_MAE_MNTNC_VW.FMR_DISCRPNCY_DFRL 
 WHERE DFRL_CREATE_TMS > CURRENT_DATE -25

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    您的诊断是正确的,所以首先,您可能需要检查会话字符集(它是连接定义的一部分)。 如果是 ASCII 将其更改为 UTF8,您将能够看到原始字符而不是替代字符。


    如果字符确实是数据的一部分,而不仅仅是编码翻译问题的指示:

    替代字符 AKA SUB(DEC:26 HEX:1A)在 Teradata 中非常独特。

    你不能直接使用它-

    select  '�';
    
    -- [6706] The string contains an untranslatable character.
    

    select  '1A'XC;
    
    -- [6706] The string contains an untranslatable character.
    

    如果您使用的是 14.0 或更高版本,您可以使用 CHR 函数生成它:

    select  chr(26);
    

    如果您低于 14.0 版,您可以像这样生成它:

    select  translate (_unicode '05D0'XC using unicode_to_latin with error);
    

    生成角色后,您现在可以将其与 REPLACEOTRANSLATE

    一起使用
    create multiset table t (i int,txt varchar(100) character set latin) unique primary index (i);
    
    insert into t (i,txt) values (1,translate ('Hello שלום world עולם' using unicode_to_latin with error));
    

    select * from t;
    
    -- Hello ���� world ����
    

    select otranslate (txt,chr(26),'') from t;
    
    -- Hello  world 
    
    select otranslate (txt,translate (_unicode '05D0'XC using unicode_to_latin with error),'') from t;
    
    -- Hello  world 
    

    顺便说一句,OTRANSLATEOREPLACE 有 2 个版本:

    • syslib 下的函数适用于 LATIN
    • TD_SYSFNLIB 下的函数适用于 UNICODE

    【讨论】:

    • 你能展示一个工作的oTranslate吗,对我来说它总是失败。 Afaik 只有 Teradata 的 Unicode 工具中的 Udf_checklatin 函数可以做到这一点:Kithttps://downloads.teradata.com/download/tools/unicode-tool-kit
    • @dnoeth,我在回答中添加了完整示例
    • 这仍然返回 Failure 6706 The string contains an untranslatable character on 15 & 15.10。在您的系统上,可能在 dbscontrol 的 internal 字段中启用了 AcceptReplacementCharacters
    • @masospaghetti 它回答了你的问题吗?你找到错误的原因了吗?
    • @Dudu Markovitz 我将您的回复标记为答案,因为它非常有用且内容丰富。我最终通过将查询包装在另一个 SELECT 语句中来“解决”这个问题。 Teradata 通过这样做自动清理了数据并去掉了替换字符。 OREPLACE 和 OTRANSLATE 在我的 Teradata 版本中不起作用。
    【解决方案2】:

    除了上面嘟嘟的出色回答之外,现在我又遇到了这个问题,有更多的时间去尝试,我想补充以下内容。以下 SELECT 命令产生了一个不可翻译的字符:

    SELECT IDENTIFY FROM PROD_MAE_MNTNC_VW.SCHD_MNTNC;
    
    IDENTIFY
    24FEB1747659193DC330A163DCL�ORD
    

    尝试直接对这个字符执行 REGEXP_REPLACE 或 OREPLACE 会产生错误:

    Failed [6706 : HY000] The string contains an untranslatable character. 
    

    我将我的 Teradata 连接中的 CHARSET 属性从 UTF8 更改为 ASCII,现在我可以看到有问题的字符,看起来像一个标签

    IDENTIFY
    

    使用 TRANSLATE_CHK 命令使用此特定转换成功并识别违规字符的位置(请注意,这不适用于 UTF8 字符集):

    TRANSLATE_CHK(IDENTIFY USING KANJI1_SBC_TO_UNICODE) AS BADCHAR
    
    BADCHAR
    28
    

    现在可以使用一些 CASE 语句来处理这个字符,以删除坏字符并保留字符串的其余部分:

    CASE WHEN TRANSLATE_CHK(IDENTIFY USING KANJI1_SBC_TO_UNICODE) = 0 THEN IDENTIFY
    ELSE SUBSTR(IDENTIFY, 1, TRANSLATE_CHK(IDENTIFY USING KANJI1_SBC_TO_UNICODE)-1)
    END AS IDENTIFY
    

    希望这对某人有所帮助。

    【讨论】:

    • 非常感谢您使用 TRANSLATE_CHK 命令。它帮助我确定了 300 万条记录中的一条违规记录。
    猜你喜欢
    • 2022-08-14
    • 2021-07-16
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2022-12-07
    相关资源
    最近更新 更多