在 Oracle 中执行内连接时如何转义字符串中的特殊字符?

How to escape special characters in string while performing inner join in Oracle?

有一个带有单词和 ID 的临时文件 table。我必须在内部将这些词与主要 table 连接起来才能获得它们的 ID。但是 temp table 可能包含特殊字符以及数字等字词。 / .digits / ,digits / digits, / -digits / digits-.在这种情况下,内部联接不会 return 值数字。如何转义这些字符以确保值 "digits" 是 returned?

我需要在 tmp 中保留特殊字符 table。只需要在加入时逃避那些。

for t in (select id,word from tmp)
LOOP
      update tmp a
      set a.word_id = (
      select b.id
      from main_table b
      where lower(a.word) = lower(b.word)
      and rownum =1
     )
      where a.word in (select word from tmp where word = t.word);
END LOOP;  

Here is the test data:

CREATE TABLE TMP
   (ID NUMBER,
    WORD VARCHAR2(4000 BYTE),
    WORD_ID NUMBER
);

CREATE TABLE main_table
   (ID NUMBER,
    WORD VARCHAR2(4000 BYTE));

insert into tmp(id,word) values ( 1, 'digits' );
insert into tmp(id,word) values ( 2, 'digits.' );
insert into tmp(id,word) values ( 3, '.digits-' );

insert into main_table values( 111, 'digits');

预期结果是将 word_id 从 main_table 更新为 tmp table。

ID    WORD      WORD_ID
1     digits     111
2     digits.    111
3     .digits-   111

您可以尝试使用 REGEXP_REPLACE 在进行比较之前删除任何非字母数字字符:

UPDATE tmp a
SET a.word_id = (SELECT b.id
                 FROM main_table b
                 WHERE REGEXP_REPLACE(a.word, '[^A-Za-z0-9]', '') = b.word);

TRANSLATE 是你的朋友。

简单定义应保留的字符 - 它们在 TRANSLATE 应删除的字符串和字符中定义相同,它们映射为 NULL。

此查询中提供了此类转换的示例

select word,
translate(lower(word),'abcdefghijklmnopqrstuvwxyz.-#*+',
                      'abcdefghijklmnopqrstuvwxyz') word_clean
from tmp;

WORD       WORD_CLEAN
---------- ----------
digits     digits    
digits.    digits    
.digits-   digits

连接看起来像这样

select tmp.word tmp_word,  main_table.word main_word
from tmp
left outer join  main_table
on translate(lower(tmp.word),'abcdefghijklmnopqrstuvwxyz.-#*+',
                          'abcdefghijklmnopqrstuvwxyz') = main_table.word

请注意,我使用 lower 来消除大写字母 - 如有需要请进行调整。

另请注意,TRANSLATE 选项将产生比 REGEXP 选项更好的性能。

一个选项是在 UPDATE 语句中子选择的 WHERE 条件中的 regexp_replace() 函数中使用 [^[:alnum:]] POSIX 模式:

regexp_replace(t.word,'[^[:alnum:]]') = m.word

其中 t 是 table tmp 的别名,mmain_table.

的别名

下面是另一种方法。

 update tmp a
      set a.word_id = (
      select b.id
      from main_table b
      where lower(a.word) like concat(concat('%',b.word),'%') 
      and rownum =1