Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将字符串与表中的数据进行比较_Sql_String_Oracle_Plsql_Special Characters - Fatal编程技术网

Sql 将字符串与表中的数据进行比较

Sql 将字符串与表中的数据进行比较,sql,string,oracle,plsql,special-characters,Sql,String,Oracle,Plsql,Special Characters,假设我有这样一个输入字符串:HÊLLÕWÖRLÐ 我还有一个表,即REPLACE_CHAR_TAB,其数据如下: SPECIAL_ASCII SPECIAL_CHAR REPLACE_ASCII REPLACE_CHAR ----------------------------------------------------------------- 169 © NULL

假设我有这样一个输入字符串:HÊLLÕWÖRLÐ

我还有一个表,即REPLACE_CHAR_TAB,其数据如下:

SPECIAL_ASCII     SPECIAL_CHAR     REPLACE_ASCII     REPLACE_CHAR
-----------------------------------------------------------------
          169                ©              NULL             NULL
          202                Ê                69                E
          208                Ð                68                D
          213                Õ                79                O
现在,我想用这个表中的数据验证输入字符串,只要在这个表中找到字符串中的特殊字符,输入字符串字符就会被这个表中的replace_CHAR替换

例如:

Input: HÊLLÕ WÖRLЩ !!
Output: HELLO WORLD !!
我是PL/SQL新手,我能得到一些关于如何实现这一点的帮助和提示吗

感谢您的指导和帮助!谢谢

您可以使用来计算字符串中每个字符的ASCII值,但是您的设计对您的性能有点危险

相反,我建议您使用。看一看:

SELECT TRANSLATE('HÊLLÕ WÖRLЩ', '©ÊÐÖÕ', ' EDOO') 
FROM DUAL;

祝你好运

试图找到一个符合您确切要求的解决方案:给定一个具有特殊字符和相应普通字符映射的表,我们需要编写PL/SQL来完成映射

  • 使用映射创建表
  • 在上面的语句中,
    special_ascii
    的值较大,因为Oracle的
    ascii
    本机支持0-127个字符。对于更大的范围,将根据数据库的字符编码返回unicode值

  • 创建一个PL/SQL
  • 在上面的PL/SQL中,我们使用了PL/SQL的特性。它本质上是一个键/值对,有助于快速查找。通过使用关联数组,我们试图避免为每个字符映射查询表

  • 样本执行
  • 此解决方案的目的是使特殊字符映射具有可伸缩性和易于理解


    链接到。

    Oracle提供了用于替换单个字符的
    翻译功能。因此,使用
    listag
    从转换表中获取字符,并使用结果字符串进行转换:

    select translate('HÊLLÕ WÖRLЩ !!', specials, replacers)
    from 
    (
      select 
        listagg(special_char,'') within group 
          (order by replace_ascii, special_ascii) as specials,
        listagg(replace_char,'') within group 
          (order by replace_ascii, special_ascii) as replacers
      from replace_char_tab
    );
    
    SQL FIDLE:

    (顺便说一句,首先按
    replace_ascii
    排序很重要,这样才能最后得到空值。因此
    TRANSLATE
    将删除相应的字符。另一个顺序将导致两个位置不匹配的字符串。)


    如您在评论中所述,如果要替换为多个字符,如
    æ
    ae
    ,则不能再使用
    TRANSLATE
    。相反,您必须使用
    REPLACE
    递归地运行翻译表,然后保留最后修改的字符串。为了一个接一个地访问翻译表记录,必须首先对记录进行编号,以便始终获得下一条记录

    with numbered as
    (
      select /*+ materialize */
        replace_char_tab.*,
        row_number() over (order by replace_ascii, special_ascii) as num 
      from replace_char_tab  
    )
    , replaced(str, num) as
    (
      select 'HÊLLÕ WÖRLЩ !!' as str, 0 as num from dual
      union all
      select
        replace(replaced.str, numbered.special_char, numbered.replace_char) as str,
        numbered.num
      from replaced 
      join numbered on numbered.num = replaced.num + 1
    )
    select max(str) keep (dense_rank last order by num) from replaced;
    

    SQL fiddle:。

    我注意到Listag和TRANSLATE的用法。但是,在特殊字符选项卡中,它包含特殊字符:和它的替换字符:ae。在这种情况下,replace_字符有2个字符,因此我认为listag和TRANSLATE解决方案将无法工作。。嗯……你说得对,那你就不能用
    翻译了。我编辑了我的答案,展示了如何使用
    REPLACE
    来迭代您的记录。谢谢您的指导。但是,对于我的需求,我需要通过表字典(replace_char_tab)进行检查。此外,实际上还有一些类似于特殊的字符:æ,替换字符:ae。在这种情况下,replace_char实际上是2个字符,我认为TRANSLATE无法生成准确的结果?
    select getSpecialCharMapping('HÊLLÕ WÖRLЩ !!') from dual;
    
    select translate('HÊLLÕ WÖRLЩ !!', specials, replacers)
    from 
    (
      select 
        listagg(special_char,'') within group 
          (order by replace_ascii, special_ascii) as specials,
        listagg(replace_char,'') within group 
          (order by replace_ascii, special_ascii) as replacers
      from replace_char_tab
    );
    
    with numbered as
    (
      select /*+ materialize */
        replace_char_tab.*,
        row_number() over (order by replace_ascii, special_ascii) as num 
      from replace_char_tab  
    )
    , replaced(str, num) as
    (
      select 'HÊLLÕ WÖRLЩ !!' as str, 0 as num from dual
      union all
      select
        replace(replaced.str, numbered.special_char, numbered.replace_char) as str,
        numbered.num
      from replaced 
      join numbered on numbered.num = replaced.num + 1
    )
    select max(str) keep (dense_rank last order by num) from replaced;