Sql 在本机查询中设置Clob值
甲骨文数据库 使用Hibernate的Spring JPA 我在将Clob值插入本机sql查询时遇到困难。 调用查询的代码如下所示:Sql 在本机查询中设置Clob值,sql,oracle,jpa,clob,nativequery,Sql,Oracle,Jpa,Clob,Nativequery,甲骨文数据库 使用Hibernate的Spring JPA 我在将Clob值插入本机sql查询时遇到困难。 调用查询的代码如下所示: @SuppressWarnings("unchecked") public List<Object[]> findQueryColumnsByNativeQuery(String queryString, Map<String, Object> namedParameters) { List<Object[]> resu
@SuppressWarnings("unchecked")
public List<Object[]> findQueryColumnsByNativeQuery(String queryString, Map<String, Object> namedParameters)
{
List<Object[]> result = null;
final Query query = em.createNativeQuery(queryString);
if (namedParameters != null)
{
Set<String> keys = namedParameters.keySet();
for (String key : keys)
{
final Object value = namedParameters.get(key);
query.setParameter(key, value);
}
}
query.setHint(QueryHints.HINT_READONLY, Boolean.TRUE);
result = query.getResultList();
return result;
}
SELECT COUNT ( DISTINCT ( <column> ) ) FROM <Table> c where (exact ( <column> , to_clob((:stringValue)), null ) = 1 )
查询字符串的格式为
SELECT COUNT ( DISTINCT ( <column> ) ) FROM <Table> c where (exact ( <column> , (:clobValue), null ) = 1 )
其中,exact,:clobValue,null=1是一个函数,clobValue是一个Clob
我可以按如下方式调整查询:
@SuppressWarnings("unchecked")
public List<Object[]> findQueryColumnsByNativeQuery(String queryString, Map<String, Object> namedParameters)
{
List<Object[]> result = null;
final Query query = em.createNativeQuery(queryString);
if (namedParameters != null)
{
Set<String> keys = namedParameters.keySet();
for (String key : keys)
{
final Object value = namedParameters.get(key);
query.setParameter(key, value);
}
}
query.setHint(QueryHints.HINT_READONLY, Boolean.TRUE);
result = query.getResultList();
return result;
}
SELECT COUNT ( DISTINCT ( <column> ) ) FROM <Table> c where (exact ( <column> , to_clob((:stringValue)), null ) = 1 )
其中,stringValue是一个字符串,但显然这只适用于最大sql字符串大小4000,我需要传入更多
我尝试使用该方法将Clob值作为java.sql.Clob传递
最终Clob clobValue=org.hibernate.engine.jdbc.ClobProxy.generateProxystringValue
这将导致java.io.NotSerializableException:org.hibernate.engine.jdbc.ClobProxy
我尝试使用
最终Clob Clob=org.hibernate.engine.jdbc.ClobProxy.generateProxystringValue;
最终Clob clobValue=SerializableClobProxy.generateProxyclob
但这似乎为确切的函数提供了错误类型的参数,导致org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144-SQL错误:29900,SQLState:99999
org.hibernate.engine.jdbc.spi.SqlExceptionHelper:146-ORA-29900:运算符绑定不存在
ORA-06553:PLS-306:调用“精确”时参数的数量或类型错误
在阅读了一些关于对实体使用CLOB的帖子后,我尝试传入一个byte[],但这也提供了错误的参数类型org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144-SQL错误:29900,SQLState:99999
org.hibernate.engine.jdbc.spi.SqlExceptionHelper:146-ORA-29900:运算符绑定不存在
ORA-06553:PLS-306:调用“精确”时参数的数量或类型错误
我也可以将值作为字符串传递,只要它不破坏最大字符串值
我看过一篇帖子,它似乎建议唯一的方法是使用普通的老JDBC。这不是一个选择。
我正面临一个艰难的最后期限,因此欢迎提供任何帮助。在这种情况下,似乎需要为Hibernate显式设置参数类型。以下代码适用于我:
Clob clob = entityManager
.unwrap(Session.class)
.getLobHelper()
.createClob(reader, length);
int inserted = entityManager
.unwrap(org.hibernate.Session.class)
.createSQLQuery("INSERT INTO EXAMPLE ( UUID, TYPE, DATA) VALUES (:uuid, :type, :data)")
.setParameter("uuid", java.util.Uuid.randomUUID(), org.hibernate.type.UUIDBinaryType.INSTANCE)
.setParameter("type", java.util.Uuid.randomUUID(), org.hibernate.type.StringType.INSTANCE)
.setParameter("data", clob, org.hibernate.type.ClobType.INSTANCE)
.executeUpdate();
Blob也有类似的解决方法。恐怕您对Oracle中CLOB的假设是错误的。在Oracle中,CLOB定位器类似于文件句柄。这样的句柄只能由数据库创建。因此,不能简单地将CLOB作为绑定变量传递。CLOB必须在某种程度上与数据库存储相关,因为它可以占用多达176TB的空间,而类似的东西不能保存在Java堆中 因此,通常的方法是以某种形式调用DB函数empty\u clob或dbms\u lob.create\u temporary。然后从数据库中获得clob,即使您认为它在参数中。然后,您可以将任意多的数据写入定位器句柄CLOB,然后您可以将此CLOB用作查询的参数
如果不遵循此模式,代码将无法工作。无论您使用JPA、SpringBatch还是PlanJDBC,这都无关紧要。这个约束由数据库给出。答案:谢谢你们两位的回答。我应该在不久前解决这个问题时更新这个。最后,我使用了JDBC,这个问题在一阵烟雾中消失了 在回答更多问题之前,请先阅读。