3

私の質問は:ではなくUTL_MATCHで動作する-のような関数はありますか?CLOBVARCHAR2

私の特定の問題は次のとおりです。私はOracleデータベースを使用しています。DomoCenterViewとインターフェイスする事前に作成されたクエリがたくさんあります。クエリには、で定義された変数が含まれています${variableName}。これらのクエリを書き直す必要があります。私はオリジナルを書いていなかったので、変数の適切な値を理解する代わりに、アプリケーションでクエリを実行し、クエリが何であるかを取得したいと思いますV$SQL

したがって、私の解決策は次のとおりUTL_MATCHです。変数を含むクエリに対してaを実行しますV$SQL.SQL_FULLTEXT。ただし、UTL_MATCHに限定されVARCHAR2、のデータ型はV$SQL.SQL_FULLTEXTですCLOBUTL_MATCHしたがって、これが、データ型で機能する-like関数を探している理由です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

UTL_MATCHは、2つの文字列がどの程度類似しているかを確認するために文字列を比較するためのパッケージです。その関数は文字列を評価し、スコアを返します。${variableName}したがって、取得するのは、 「Farmville」または「StackOveflow」に変換 する必要のある編集の数を示す数値だけです。

実際の違いはわかりません。これらの2つのテキスト文字列は${variableName}、「Farmville」に置き換えられるオフセット123を除いて、同じです。

そのように置くことは、別のアプローチを示唆しています。INSTR ()およびSUBSTR()${variableName}を使用して、Domo CenterViewクエリ内ののインスタンスを検索し、それらのオフセットを使用して、v$sql.fulltext同等のテキスト内の異なるテキストを識別します。これは、 DBMS_LOBパッケージを使用したPL/SQLのCLOBで実行できます。

于 2012-05-22T14:14:54.173 に答える
1

CLOB検索するテキストの長さが32767未満の場合は、次をVARCHAR2使用してに変換できます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

そのためのカスタム関数を作成することになりました。コードは次のとおりです。

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 に答える