Sql Oracle中like语句中的替换
我有一个名为syns的Sql Oracle中like语句中的替换,sql,database,oracle,query-optimization,sql-like,Sql,Database,Oracle,Query Optimization,Sql Like,我有一个名为syns的同义词表,用于存储单词和现有同义词。同样,还有另一个名为subs的表,它包含单词的替换。这些表用于在名为institutions的主表中查找类似值,该主表承载数据库中的现有名称 这样做的目的是为了避免在同义词和单词替换方面出现相似的名称。用户提供了一个新的机构名称,在插入机构表之前,有几个查询将每个单词替换为同义词和替换词。例如,我有以下数据: substitution word table: WORD SUBS_LIST MOUNTAIN MOUNTAIN,
同义词表
,用于存储单词和现有同义词。同样,还有另一个名为subs的表,它包含单词的替换。这些表用于在名为institutions
的主表中查找类似值,该主表承载数据库中的现有名称
这样做的目的是为了避免在同义词和单词替换方面出现相似的名称。用户提供了一个新的机构名称,在插入机构表之前,有几个查询将每个单词替换为同义词和替换词。例如,我有以下数据:
substitution word table:
WORD SUBS_LIST
MOUNTAIN MOUNTAIN, MOUNT, MT, MTN
VIEW VIEW, VU
FORMULA FORMULA, 4MULA
institution表包含数据库中所有现有的名称。然后,当接收到一个新名称时,用其各自的同义词列表和单词替换替换每个单词时,这不必类似。例如,由于现有记录FORMULA VIEW UNIVERSITY
,应在数据库中找到一个新名称,如FORMULA VU SCHOOL
我创造了这个想法。然而,我没有得到任何结果
谢谢你能证实我的理解吗
搜索字符串“FORMULA VU SCHOOL”的第一部分是“FORMULA”,如果有以“FORMULA”开头的字符串,则需要在表中检查该字符串。
在这种情况下,有一个热门的“公式视图大学”
然后获取字符串的第二部分(“视图”),并在表subs中查找它
然后取字符串的第三部分(“UNIVERSITY”)并在syns表中查找它
之后,表中找到的字符串将转换为
公式视图大学=公式视图教育
由于我们正在寻找“公式VU学校”是否已经存在,当以上述方式翻译时,我们将得到
公式学校=公式观点教育
由于表机构中已经存在这样的转换记录,因此需要在预期输出中按如下方式显示该记录
Existing_column_value search_string_value
FORMULA VIEW UNIVERSITY FORMULA VU SCHOOL
您能确认这是否是您要找的吗?下面的功能似乎正在工作。它使用一种将逗号分隔的字符串拆分为单词的技术,您可以应用另一种。但最好的办法是将数据模型更改为单词同义词,这样可以避免拆分,因为拆分可能不可靠。您可以在检查新条目时使用此功能,例如:
where replace_synonyms(inserted_value) <> replace_synonyms(existing_value)
功能:
create or replace function replace_synonyms(i_text in varchar2) return varchar2
is
p_text varchar2(4000) := i_text;
cursor c_subs is
select word, trim(column_value) text
from subs, xmltable(('"' ||replace(subs_list, ',', '","') || '"'))
where p_text like '%'||trim(column_value)||'%'
union
select word, trim(column_value) text
from syns, xmltable(('"' ||replace(syn_list, ',', '","') || '"'))
where p_text like '%'||trim(column_value)||'%';
begin
for i in c_subs
loop
p_text := regexp_replace(
p_text, '(^|[^a-z0-9])' || i.text || '($|[^a-z0-9])',
'\1' || i.word || '\2', 1, 0, 'i');
end loop;
return p_text;
end;
这有点不同。为了更清楚,让我们稍微更改一下示例。假设我们有4MULA VU学校
。每个单词都需要检查单词替换和同义词。例如,第一个单词4MULA
,只进行单词替换,然后将其更改为公式,然后第二个单词VU
,也只进行单词替换,然后将其替换为VIEW
。最后一个单词SCHOOL
通过单词替换进行检查,但它没有,然后我们检查同义词列表,发现“SCHOOL”与“UNIVERSITY”在同一列表中。因此,4MULA VU学校
被认为与FORMULA VIEW大学
相同,谢谢@Pound Stibbons,这是一个漂亮的解决方案。只是一个问题,这个词何时出现在两个类别中?我白天一直在思考,但我还没能想出一个办法,根据一个单词所属类别的数量来获取多个记录。举一个更具体的例子,请看一下这个提琴:当一个单词匹配多个类别时,我试图将可能的值存储在一个数组中,但我得到了“ORA-06532:下标超出限制,但我增加了数组的大小”。请检查这个最新版本,尝试使用一个工作版本来处理多个类别中匹配的单词:看起来我的dbfiddle作为PL/SQL块工作,但是在将其转换为函数时遇到了一个错误。我得到错误:ORA-06502:PL/SQL:numeric或value错误:第37行的字符到数字转换错误:array(1):=p_text代码>。在PL/SQL块中,我得到了正确的记录,但现在我得到了错误。你知道我怎么修吗?你认为这是一个很好的方法吗?我曾经在同义词列表中找到一个在不同类别中有几个匹配项的单词?非常感谢这个错误,我试图在简化的示例中复制它,但什么也没发现。您必须调试值并查看转换的内容。但我不会存储与WORD
和SYN\u列表的一部分相同的值。这是通向无限循环的直接途径。你认为数组中的存储方式是ehen I使用多个同义词的方式吗?
where replace_synonyms(inserted_value) <> replace_synonyms(existing_value)
select replace_synonyms('FORMULA VIEW UNIVERSITY') from dual;
-- FORMULA VIEW EDUCATION
select replace_synonyms('CANTINA TRAINING MT') from dual;
-- FOOD EDUCATION MOUNTAIN
create or replace function replace_synonyms(i_text in varchar2) return varchar2
is
p_text varchar2(4000) := i_text;
cursor c_subs is
select word, trim(column_value) text
from subs, xmltable(('"' ||replace(subs_list, ',', '","') || '"'))
where p_text like '%'||trim(column_value)||'%'
union
select word, trim(column_value) text
from syns, xmltable(('"' ||replace(syn_list, ',', '","') || '"'))
where p_text like '%'||trim(column_value)||'%';
begin
for i in c_subs
loop
p_text := regexp_replace(
p_text, '(^|[^a-z0-9])' || i.text || '($|[^a-z0-9])',
'\1' || i.word || '\2', 1, 0, 'i');
end loop;
return p_text;
end;