2

我有一个具有 CLOB 属性的实体:

public class EntityS {
  ...
  @Lob
  private String description;
}

为了从数据库中检索某些实体,我们使用 CriteriaQuery,我们需要结果是唯一的,所以我们这样做:

query.where(builder.and(predicates.toArray(new Predicate[predicates.size()]))).distinct(true).orderBy(builder.asc(root.<Long> get(EntityS_.id)));

如果我们这样做,我们会收到以下错误:

ORA-00932: inconsistent datatypes: expected - got CLOB

我知道那是因为在选择 CLOB 时不能使用 distinct。但是我们需要 CLOB。是否有使用 CriteriaQuery 和谓词等的解决方法?

我们正在使用一个丑陋的解决方法来摆脱 .unique(true) 然后过滤结果,但那是废话。我们使用它只是为了能够继续开发应用程序,但我们需要一个更好的解决方案,我似乎没有找到一个......

4

2 回答 2

1

如果您使用 Hibernate 作为持久性提供程序,您可以指定以下查询提示:

query.setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false);

这样,“distinct”不会传递给 SQL 命令,但 Hibernate 将负责只返回不同的值。

有关更多信息,请参见此处:https ://thoughts-on-java.org/hibernate-tips-apply-distinct-to-jpql-but-not-sql-query/

于 2019-12-09T09:37:34.343 回答
0

跳出框框思考——我不知道这是否可行,但也许值得一试。(我对其进行了测试,它似乎可以工作,但我创建了一个只有一列、CLOB 数据类型和两行的表,两者都有值to_clob('abcd')- 当然它应该适用于设置。)

要进行重复数据删除,请计算每个 clob 的哈希值,并指示 Oracle 计算按哈希值分区并按空(null)排序的行号。然后只选择行号为 1 的行。如下所示(t是我创建的表,其中一个名为 CLOB 列c)。

我希望执行时间应该相当不错。当然,最大的担忧是碰撞。不错过任何 CLOB 有多重要,首先在基表中有多少行?发生碰撞的“十亿分之一的机会”是否可以接受?

select c
from (
select c, row_number() over (partition by dbms_crypto.hash(c, 3) order by null) as rn
from t
)
where rn = 1;

注意 - 用户(您的应用程序,在您的情况下)必须EXECUTESYS.DBMS_CRYPTO. 如果需要,DBA 可以授予它。

于 2017-02-10T16:57:59.620 回答