Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.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 Oracle中like语句中的替换_Sql_Database_Oracle_Query Optimization_Sql Like - Fatal编程技术网

Sql Oracle中like语句中的替换

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,

我有一个名为syns的
同义词表
,用于存储单词和现有同义词。同样,还有另一个名为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;