19

COPIA というテーブルに含まれる (CLOB 型の) CLOB_COLUMN という列を想定できる固有の CLOB 値を見つけたいと考えています。

この問題を解決するために PROCEDURAL WAY を選択しましたが、次のように単純な SELECT を使用することをお勧めします: SELECT DISTINCT CLOB_COLUMN FROM TABLE でエラー「ORA-00932: データ型に一貫性がありません: 予想される - CLOB を取得しました」を回避します。

どうすればこれを達成できますか?

よろしくお願いいたします。これは私が考えた手続き的な方法です:

-- Find the distinct CLOB values that can assume the column called CLOB_COLUMN (of type CLOB)
-- contained in the table called COPIA
-- Before the execution of the following PL/SQL script, the CLOB values (including duplicates) 
-- are contained in the source table, called S1
-- At the end of the excecution of the PL/SQL script, the distinct values of the column called CLOB_COLUMN
-- can be find in the target table called S2

BEGIN
   EXECUTE IMMEDIATE 'TRUNCATE TABLE S1 DROP STORAGE';

   EXECUTE IMMEDIATE 'DROP TABLE S1 CASCADE CONSTRAINTS PURGE';
EXCEPTION
   WHEN OTHERS
   THEN
      BEGIN
         NULL;
      END;
END;

BEGIN
   EXECUTE IMMEDIATE 'TRUNCATE TABLE S2 DROP STORAGE';

   EXECUTE IMMEDIATE 'DROP TABLE S2 CASCADE CONSTRAINTS PURGE';
EXCEPTION
   WHEN OTHERS
   THEN
      BEGIN
         NULL;
      END;
END;

CREATE GLOBAL TEMPORARY TABLE S1
ON COMMIT PRESERVE ROWS
AS
   SELECT CLOB_COLUMN FROM COPIA;

CREATE GLOBAL TEMPORARY TABLE S2
ON COMMIT PRESERVE ROWS
AS
   SELECT *
     FROM S1
    WHERE 3 = 9;

BEGIN
   DECLARE
      CONTEGGIO   NUMBER;

      CURSOR C1
      IS
         SELECT CLOB_COLUMN FROM S1;

      C1_REC      C1%ROWTYPE;
   BEGIN
      FOR C1_REC IN C1
      LOOP
         -- How many records, in S2 table, are equal to c1_rec.clob_column?
         SELECT COUNT (*)
           INTO CONTEGGIO
           FROM S2 BETA
          WHERE DBMS_LOB.
                 COMPARE (BETA.CLOB_COLUMN,
                          C1_REC.CLOB_COLUMN) = 0;

         -- If it does not exist, in S2, a record equal to c1_rec.clob_column, 
         -- insert c1_rec.clob_column in the table called S2
         IF CONTEGGIO = 0
         THEN
            BEGIN
               INSERT INTO S2
                    VALUES (C1_REC.CLOB_COLUMN);

               COMMIT;
            END;
         END IF;
      END LOOP;
   END;
END;
4

7 に答える 7

13

フィールドを 32767 文字に切り詰めることが許容される場合、これは機能します。

select distinct dbms_lob.substr(FIELD_CLOB,32767) from Table1
于 2016-12-14T13:04:21.103 に答える
8

CLOB のハッシュを比較して、それらが異なるかどうかを判断できます。

SELECT your_clob
  FROM your_table
 WHERE ROWID IN (SELECT MIN(ROWID) 
                   FROM your_table
                  GROUP BY dbms_crypto.HASH(your_clob, dbms_crypto.HASH_SH1))

編集:

このHASH関数は、衝突がないことを保証しません。ただし、設計上、衝突が発生する可能性はほとんどありません。それでも、衝突のリスク (<2^80?) が許容できない場合dbms_lob.compareは、同じハッシュを持つ行のサブセットを (と) 比較することで、クエリを改善できます。

于 2010-10-13T11:28:45.353 に答える
6

このアプローチを使用してください。テーブルプロファイルの列の内容はNCLOBです。実行にかかる時間が長くなるwhere句を追加しました。

with
  r as (select rownum i, content from profile where package = 'intl'),
  s as (select distinct (select min(i) from r where dbms_lob.compare(r.content, t.content) = 0) min_i from profile t where t.package = 'intl')
select (select content from r where r.i = s.min_i) content from s
;

効率性で賞を獲得しようとはしていませんが、うまくいくはずです。

于 2010-10-13T10:10:06.333 に答える
0

Oracle エラーを回避するには、次のようにする必要があります。

SELECT CLOB_COLUMN FROM TABLE COPIA C1 WHERE C1.ID IN (SELECT DISTINCT C2.ID FROM COPIA C2 WHERE ....)

于 2013-09-11T15:57:25.677 に答える