在 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
的别名,m
是 main_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
有一个带有单词和 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
的别名,m
是 main_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