2016-05-20 8 views
1

にVARCHAR2から列を変換した後、私はOracleのクエリを持って実行するクエリがCLOB

select id from (
    select ID, ROW_NUMBER() over (partition by LATEST_RECEIPT order by ID) rownumber 
    from Table 
    where LATEST_RECEIPT in 
    (
     select LATEST_RECEIPT from Table 
     group by LATEST_RECEIPT 
     having COUNT(1) > 1 
    ) 
) t 
where rownumber <> 1; 

を失敗しLATEST_RECEIPTのデータ型は、以前のVARCHAR2(4000)であり、このクエリがうまく働きました。列の長さを拡張する必要があるので、CLOBに変更しましたが、その後は失敗します。誰も私がこの問題を解決したり、回避策を提供したりするのを手伝ってもらえますか?

+1

どのようなエラーがスローされますか? –

+0

ORA00932-データ型が予期しないもの:clob – Vasanthan

+3

これはCLOB/BLOBを使用する際の欠点の1つで、索引では使用できず、GROUP BYや他のagregate関数でも使用できません。私はあなたがそれを 'VARCHAR(ずっと長い)'データ型に戻さなければならないと思う。 –

答えて

1

同じlast_receipt値で、異なるID(IDが一意であると仮定)を持つ他の行を探すように内部クエリを変更できます。別の行が存在する場合、それは1より大きい値を返すカウントに相当します。しかし、あなたは単に平等のための2つのCLOB値をテストすることはできません、あなたはdbms_lob.compareを使用する必要があります:あなたはまた、分析partition by句でCLOBを使用することはできませんとして、行番号のフィルタを適用する

select ID 
from your_table t1 
where exists (
    select null from your_table t2 
    where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0 
    and t2.ID != t1.ID 
    -- or if ID isn't unique: and t2.ROWID != t1.ROWID 
); 

は、トリッカーです。 AndréSchildが示唆したように、あなたはハッシュを使うことができます。ここで(!将来のリリースで変更される可能性が理論的にかかわらず)dbms_crypto.hash_sh1の同等の整数値3を、渡す:

select id from (
    select ID, ROW_NUMBER() over (partition by dbms_crypto.hash(LATEST_RECEIPT, 3) 
     order by ID) rownumber 
    from your_table t1 
    where exists (
     select null from your_table t2 
     where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0 
     and t2.ID != t1.ID 
     -- or if ID isn't unique: and t2.ROWID != t1.ROWID 
    ) 
) 
where rownumber > 1; 

ハッシュ衝突を取得することももちろん可能であり、それが起こった場合 - 両方とも同じ値にハッシュ化された2つのlatest_receiptの値があったとすると、あまりにも多くの行を戻すことができます。それは考えにくいかもしれませんが、考慮する必要があります。

そうではなく、あなたが唯一のlastest_receipt同じと下位ID持つ行を探すことができます注文:

select ID 
from your_table t1 
where exists (
    select null from your_table t2 
    where dbms_lob.compare(t2.LATEST_RECEIPT, t1.LATEST_RECEIPT) = 0 
    and t2.ID < t1.ID 
); 

ここでもIDが一意であると仮定し。そうでない場合は、代わりにrowidを使用することができますが、見つかった行の制御が少なくなります.rowidの最小値は必ずしも最小のIDである必要はありません。おそらく、これを使用して行を削除して削除します。あなたが実際にあなたが削除しておくと、これはどの行気にしないなら、あなたはまだやることができます:

and t2.ROWID < t1.ROWID 

しかし、小型にもかかわらず、あなたは現在、おそらく受け入れられないことを注文すると、ハッシュが望ましいかもしれないので、リスク。

関連する問題