3

我的问题是:是否有UTL_MATCH与 aCLOB而不是 a一起使用的 -like 函数VARCHAR2

我的具体问题是:我在 Oracle 数据库上。我有一堆与 Domo CenterView交互的预先编写的查询。查询中包含由 定义的变量${variableName}。我需要重写这些查询。我没有写原件,所以我不想弄清楚变量的好值应该是什么,而是想用应用程序运行查询并获取查询的来源V$SQL

所以我的解决方案是:UTL_MATCH查询中使用变量 stuff 和V$SQL.SQL_FULLTEXT. 但是,UTL_MATCH仅限于VARCHAR2且数据类型V$SQL.SQL_FULLTEXTCLOB. 所以,这就是为什么我正在寻找一个UTL_MATCH适用于数据类型的类似函数的原因CLOB

欢迎任何其他有关如何完成此操作的提示。谢谢!

编辑,关于提示。如果您对如何执行此操作有更好的了解,让我告诉您一些我掌握的信息。我有大约 100 个查询,它们都在一个 excel 电子表格中(其中包含 的${variableName}那些)。所以我可以很容易地使用 excel 为我编写查询。我希望将所有这些查询合并在一起并将输出复制到另一张表。无论如何,如果您认为有更好的方法来做到这一点,这可能会有所帮助。

一个例子:假设我有来自 Domo 的以下查询:

select department.dept_name
from department
where department.id = '${selectedDepartmentId}'
;

我想这样称呼:

select v.sql_fulltext
from v$sql v
where utl_match.jaro_winkler_similarity(v.sql_fulltext,
'select department.dept_name
from department
where department.id = ''${selectedDepartmentId}''') > 90
;

并得到这样的回报:

SQL_FULLTEXT
------------------------------------------
select department.dept_name
from department
where department.id = '154'

我试过的:

我尝试对 clob 进行子串化并将其转换为 varchar。我真的希望这会奏效,但它给了我一个错误。这是代码:

select v.sql_fulltext
from v$sql v
where  utl_match.jaro_winkler_similarity( cast( substr (v.sql_fulltext, 0, 4000) as varchar2 (4000)),
'select department.dept_name
from department
where department.id = ''${selectedDepartmentId}''') > 90
;

这是错误:

ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 8000, maximum: 4000)

但是,如果我运行它,它工作正常:

select cast(substr(v.sql_fulltext, 0, 4000) as varchar2 (4000))
from v$sql v
;

所以我不确定转换子字符串有什么问题......

4

3 回答 3

1

如果您要搜索的文本长度 <= 32767,那么您可以将 转换CLOBVARCHAR2using DBMS_LOB.SUBSTR

select v.sql_fulltext 
from v$sql v 
where utl_match.jaro_winkler_similarity(dbms_lob.substr(v.sql_fulltext), 'select department.dept_name from department where department.id = ''${selectedDepartmentId}''') > 90 ;
于 2012-05-22T16:19:27.153 回答
1

UTL_MATCH 是一个用于比较字符串的包装,用于检查两个字符串的相似程度。它的函数评估字符串并返回分数。因此,您将得到的只是一个数字,指示(例如)您需要进行多少次编辑才能${variableName}变成“Farmville”或“StackOveflow”。

您不会得到实际差异:这两个文本字符串是相同的,除了偏移量 123 处它替换${variableName}为“Farmville”。

这么说意味着另一种方法。使用INSTR()SUBSTR()${variableName}在 Domo CenterView 查询中定位实例,并使用这些偏移量来识别v$sql.fulltext等效文本中的不同文本。您可以使用 PL/SQL 中的 CLOB 和DBMS_LOB 包来执行此操作。

于 2012-05-22T14:14:54.173 回答
1

我最终为它创建了一个自定义函数。这是代码:

CREATE OR REPLACE function match_clob(clob_1 clob, clob_2 clob) return number as

similar number := 0;
sec_similar number := 0;
sections number := 0;
max_length number := 3949;
length_1 number;
length_2 number;
vchar_1 varchar2 (3950);
vchar_2 varchar2 (3950);

begin
  length_1 := length(clob_1);
  length_2 := length(clob_2);
  --dbms_output.put_line('length_1: '||length_1);
  --dbms_output.put_line('length_2: '||length_2);
  IF length_1 > max_length or length_2 > max_length THEN

    FOR x IN 1 .. ceil(length_1 / max_length) LOOP

      --dbms_output.put_line('((x-1)*max_length) + 1'||(x-1)||' * '||max_length||' = '||(((x-1)*max_length) + 1));

      vchar_1 := substr(clob_1, ((x-1)*max_length) + 1, max_length);
      vchar_2 := substr(clob_2, ((x-1)*max_length) + 1, max_length);

--      dbms_output.put_line('Section '||sections||' vchar_1: '||vchar_1||' ==> vchar_2: '||vchar_2);

      sec_similar := UTL_MATCH.JARO_WINKLER_SIMILARITY(vchar_1, vchar_2);

      --dbms_output.put_line('sec_similar: '||sec_similar);

      similar := similar + sec_similar;
      sections := sections + 1;

    END LOOP;

    --dbms_output.put_line('Similar: '||similar||' ==> Sections: '||sections);
    similar := similar / sections;

  ELSE
    similar := UTL_MATCH.JARO_WINKLER_SIMILARITY(clob_1,clob_2);
  END IF;
  --dbms_output.put_line('Overall Similar: '||similar);
   return(similar);
end;
/
于 2012-05-24T14:26:15.347 回答