Oracle 存储过程因复杂类型的 clob 而失败,并带有 ORA-22922
Posted
技术标签:
【中文标题】Oracle 存储过程因复杂类型的 clob 而失败,并带有 ORA-22922【英文标题】:Oracle stored procedure fails with clob in complex type with ORA-22922 【发布时间】:2021-10-25 14:21:50 【问题描述】:我有一个包含存储过程和类型定义的包:
CREATE OR REPLACE package sample_pkg
authid definer
as
type r_file_info_type is record
(
id number,
file_data clob
);
procedure clob_test_complex_out
(
i_char_num in number,
o_file_info out sample_pkg.r_file_info_type
);
end;
CREATE OR REPLACE package body sample_pkg
as
procedure clob_test_complex_out
(
i_char_num in number,
o_file_info out sample_pkg.r_file_info_type
)
as
begin
o_file_info.id := i_char_num;
o_file_info.file_data := 'ABCD';
end;
end;
我试图从 Spring Boot 应用程序中调用它
package hu.sample.service
import org.springframework.jdbc.`object`.StoredProcedure
import org.springframework.jdbc.core.SqlOutParameter
import org.springframework.jdbc.core.SqlParameter
import org.springframework.stereotype.Repository
import java.math.BigDecimal
import java.sql.CallableStatement
import java.sql.SQLData
import java.sql.SQLInput
import java.sql.SQLOutput
import java.sql.Types
import javax.sql.DataSource
data class FileWithData(
var id: BigDecimal? = null,
var fileData: ByteArray? = null,
)
class FileWithDataWrapper() : SQLData
val file: FileWithData = FileWithData()
override fun getSQLTypeName(): String = "SAMPLE_PKG.R_FILE_INFO_TYPE"
override fun readSQL(input: SQLInput?, p1: String?)
file.id = input?.readBigDecimal()
val clob = input?.readClob()
clob?.getSubString(1, clob.length().toInt())
override fun writeSQL(output: SQLOutput)
output.writeBigDecimal(file.id)
output.writeClob(null)
@Repository
class ReproduceClobProblem(ds: DataSource) : StoredProcedure(ds, "SAMPLE_PKG.CLOB_TEST_COMPLEX_OUTt")
init
sql = """
|call SAMPLE_PKG.CLOB_TEST_COMPLEX_OUT(
|I_CHAR_NUM => :I_CHAR_NUM,
|O_FILE_INFO => :O_FILE_INFO
|)
|""".trimMargin()
isSqlReadyForUse = true
declareParameter(SqlParameter("I_CHAR_NUM", Types.NUMERIC))
declareParameter(SqlOutParameter("O_FILE_INFO", Types.STRUCT, "SAMPLE_PKG.R_FILE_INFO_TYPE") statement: CallableStatement, paramIndex: Int, sqlType: Int, typeName: String? ->
statement
.connection
.typeMap["SAMPLE_PKG.R_FILE_INFO_TYPE"] = FileWithDataWrapper::class.java
statement.getObject(paramIndex)
)
fun clobTest(charNum: BigDecimal): String
val result = execute connection ->
mapOf(
"I_CHAR_NUM" to charNum
)
return String((result["O_DATA"] as FileWithDataWrapper).file.fileData ?: ByteArray(0))
但它失败并出现 ORA-22922 不存在的 LOB 值错误:
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [
call SAMPLE_PKG.CLOB_TEST_COMPLEX_OUT(
I_CHAR_NUM => :I_CHAR_NUM,
O_FILE_INFO => :O_FILE_INFO
)
]; SQL state [99999]; error code [22922]; ORA-22922: nem létező LOB érték
; nested exception is java.sql.SQLException: ORA-22922: nem létező LOB érték
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1542) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1206) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1245) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:159) ~[spring-jdbc-5.3.9.jar:5.3.9]
at hu.sample.service.ReproduceClobProblem.clobTest(ReproduceClobProblem.kt:66) ~[main/:na]
at hu.sample.service.ReproduceClobProblem$$FastClassBySpringCGLIB$$d22f2772.invoke(<generated>) ~[main/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.9.jar:5.3.9]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.9.jar:5.3.9]
at hu.sample.service.ReproduceClobProblem$$EnhancerBySpringCGLIB$$a09500e1.clobTest(<generated>) ~[main/:na]
at hu.sample.controller.SampleController.reproduceProblem(SampleController.java:236) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.9.jar:5.3.9]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.9.jar:5.3.9]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.9.jar:5.3.9]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[jakarta.servlet-api-4.0.4.jar:4.0.4]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.zalando.logbook.servlet.LogbookFilter.doFilter(LogbookFilter.java:71) ~[logbook-servlet-2.4.2.jar:na]
at org.zalando.logbook.servlet.HttpFilter.doFilter(HttpFilter.java:31) ~[logbook-servlet-2.4.2.jar:na]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.5.1.jar:5.5.1]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.3.9.jar:5.3.9]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.zalando.logbook.servlet.LogbookFilter.doFilter(LogbookFilter.java:71) ~[logbook-servlet-2.4.2.jar:na]
at org.zalando.logbook.servlet.SecureLogbookFilter.doFilter(SecureLogbookFilter.java:32) ~[logbook-servlet-2.4.2.jar:na]
at org.zalando.logbook.servlet.HttpFilter.doFilter(HttpFilter.java:31) ~[logbook-servlet-2.4.2.jar:na]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.5.3.jar:2.5.3]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.9.jar:5.3.9]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.9.jar:5.3.9]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:280) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:260) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100) ~[undertow-servlet-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852) ~[undertow-core-2.2.9.Final.jar:2.2.9.Final]
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1423) ~[jboss-threads-3.1.0.Final.jar:3.1.0.Final]
at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280) ~[xnio-api-3.8.4.Final.jar:3.8.4.Final]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Caused by: java.sql.SQLException: ORA-22922: nem létező LOB érték
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:628) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:557) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:552) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4C8TTILob.processError(T4C8TTILob.java:914) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:726) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:291) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4C8TTILob.getLength(T4C8TTILob.java:234) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.T4CConnection.length(T4CConnection.java:5330) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.OracleClob.lengthInternal(OracleClob.java:302) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.OracleClob.length(OracleClob.java:270) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.sql.CLOB.length(CLOB.java:345) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at hu.sample.service.FileWithDataWrapper.readSQL(ReproduceClobProblem.kt:33) ~[main/:na]
at oracle.sql.STRUCT.toClass(STRUCT.java:630) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.sql.STRUCT.toJdbc(STRUCT.java:581) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.NamedTypeAccessor.getObject(NamedTypeAccessor.java:197) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.NamedTypeAccessor.getObject(NamedTypeAccessor.java:135) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.OracleCallableStatement.getObject(OracleCallableStatement.java:1783) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.OracleCallableStatementWrapper.getObject(OracleCallableStatementWrapper.java:679) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.getObject(HikariProxyCallableStatement.java) ~[HikariCP-4.0.3.jar:na]
at hu.sample.service.ReproduceClobProblem._init_$lambda-0(ReproduceClobProblem.kt:60) ~[main/:na]
at org.springframework.jdbc.core.JdbcTemplate.extractOutputParameters(JdbcTemplate.java:1345) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.lambda$call$6(JdbcTemplate.java:1256) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1190) ~[spring-jdbc-5.3.9.jar:5.3.9]
... 132 common frames omitted
如何在 Spring Boot 中从 Struct 中获取 Oracle Clob 值?
我已经用 Oracle 19c 试过了。
【问题讨论】:
你能显示package
和type
的定义吗?你发了两次package body
....
我已经添加了缺少的包头(包和类型定义)
【参考方案1】:
我可以用普通的JDBC
重现相同的异常
18c Express Edition Release 18.0.0.0.0 and
DriverVersion 12.1.0.2.0
这里是最小的例子
def type_name = "TEST_CLOB_RECORD.R_CLOB_TYPE"
CallableStatement stmt = null
stmt = con.prepareCall(" call TEST_CLOB_RECORD.GET_CLOB_RECORD(?) ")
stmt.registerOutParameter(1, Types.STRUCT, type_name)
stmt.execute()
Struct outStruct = stmt.getObject(1)
println outStruct.class.name
println outStruct.dump()
到这里 OK - getObject
返回 oracle.sql.STRUCT
类,dump()
为
name = TEST_CLOB_RECORD.R_CLOB_TYPE
length = 1
TXT = oracle.sql.CLOB@6df20ade
getAttributes()
返回CLOB
的副本,但对内容的任何访问都会导致ORA-22922
clob = outStruct.getAttributes()[0]
println clob.dump()
println clob.getSubString(1, (int) clob.length())
给予
<oracle.sql.CLOB@4287d447 dbaccess=oracle.jdbc.driver.T4CConnection@22b53226 dbChunkSize=-1 csform=1 isFree=false fromObject=true cachedLengthOfClobInChars=-1 prefetchData=null prefetchDataSize=0 activePrefetch=false dilCharacterSet=null acProxy=null physicalConnection=oracle.jdbc.driver.T4CConnection@22b53226 data=[0, 38, 0, 0, 66, 8, -128, 0, 0, 2, 4, -101, 0, 0, 1, 10, 0, 0, 0, 1, 3, 105, 0, 12, 0, 0, 0, 0, 0, 2, -100, -78, -69, -106, 0, 0, 0, 0, 0, 0]>
Caught: java.sql.SQLException: ORA-22922: Nonexistent LOB Value
所以在这里我建议联系 Oracle 支持并询问解释...(请参阅下面的简化 PL/SQL 代码)
确实有效虽然非常基本的解决方法是在 PL/SQL 块中获取 record
并将 CLOB 作为(附加)返回值传递 -这里的相关人员剪断了
stmt = con.prepareCall("""declare
v_clob_type test_clob_record.r_clob_type;
begin
test_clob_record.get_clob_record(o_clob_type => v_clob_type);
? := v_clob_type.txt;
end;""")
stmt.registerOutParameter(1, OracleTypes.CLOB)
stmt.execute()
def clob = stmt.getClob(1)
PL/SQL 代码
CREATE OR REPLACE package test_clob_record
as
type r_clob_type is record
(
txt clob
);
procedure get_clob_record
(
o_clob_type out test_clob_record.r_clob_type
);
end;
/
CREATE OR REPLACE package body test_clob_record
as
procedure get_clob_record
(
o_clob_type out test_clob_record.r_clob_type
)
as
begin
o_clob_type.txt := cast ('ABCD' as CLOB);
end;
end;
/
【讨论】:
我之前尝试过这种解决方案,但这并不是我真正想要的。我编写了一个生成此代码的工具,因此结构可以位于数组或其他复杂结构中,因此我不能使用这种解决方法。我的同事找到了其他解决方案,如果数据来自表 clob 字段,它似乎正在工作。以上是关于Oracle 存储过程因复杂类型的 clob 而失败,并带有 ORA-22922的主要内容,如果未能解决你的问题,请参考以下文章
oracle中LOBSEGMENT类型存储的clob的内容过大,如何清除clob字段内容。释放表空间!