6

在返回 refcursor 的 Oracle 中调用存储过程时出现错误

2011-05-10 03:36:23 DirtiesContextTestExecutionListener [DEBUG] After test method: context [[TestContext@3a363a36 testClass = AccountActivityServiceTest, locations = array<String>['classpath:/com/bnymellon/pwb/pfdetails/service/test/test-application-context.xml'], testInstance = com.bnymellon.pwb.pfdetails.service.test.AccountActivityServiceTest@6d2c6d2c, testMethod = getData@AccountActivityServiceTest, testException = org.springframework.jdbc.UncategorizedSQLException: 
### Error updating database.  Cause: java.sql.SQLException: ORA-08103: object no longer exists

### The error may involve com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper.getAccountActivityData-Inline
### The error occurred while setting parameters
### Cause: java.sql.SQLException: ORA-08103: object no longer exists

; uncategorized SQLException for SQL []; SQL state [72000]; error code [8103]; ORA-08103: object no longer exists
; nested exception is java.sql.SQLException: ORA-08103: object no longer exists 

我正在使用 Spring MyBatis 集成项目。MyBatis 的版​​本是 3.0.4

我可以看到程序正在执行。日志如下。

2011-05-10 03:36:16 PreparedStatement [DEBUG] ==>  Executing: {call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)} 
2011-05-10 03:36:16 PreparedStatement [DEBUG] ==> Parameters: 1987(Integer), 5627(Integer), null, null, 2010-01-01(Date), 2010-12-31(Date), All Asset Classes(String), [All, PYR](String), (String), null

我的映射器 XML 如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper">
    <select id="getAccountActivityData"
        parameterType="com.bnymellon.pwb.pfdetails.common.AccountActivityDTO"
        statementType="CALLABLE">
        {call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY(
        #{userInstance,mode=IN, jdbcType=INTEGER},
        #{accountGroupId,mode=IN,
        jdbcType=INTEGER},
        #{accountId,mode=IN, jdbcType=VARCHAR},
        #{accountId,mode=IN, jdbcType=VARCHAR},
        #{startDate,mode=IN,
        jdbcType=DATE},
        #{endDate,mode=IN, jdbcType=DATE},
        #{assetClass,mode=IN, jdbcType=VARCHAR},
        #{transactionType,mode=IN,
        jdbcType=VARCHAR},
        #{cusipId,mode=IN, jdbcType=VARCHAR},
        #{ticker,mode=IN, jdbcType=VARCHAR},
        #{domainList,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=aaDataMap})}
    </select>

    <resultMap type="com.bnymellon.pwb.pfdetails.domain.AccountActivity"
        id="aaDataMap">
        <result column="TICKER" property="ticker" jdbcType="VARCHAR" />
        <result column="CUSIP" property="cusIp" jdbcType="VARCHAR" />
        <result column="SECURITY_NAME" property="securityName"
            jdbcType="VARCHAR"></result>
        <result column="ASSET_CLASS" property="assetClass" jdbcType="VARCHAR" />
        <result column="TRADE_DATE" property="tradeDate" jdbcType="DATE" />
        <result column="SETTLE_DATE" property="settleDate" jdbcType="DATE" />
        <result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
        <result column="RECORD_TYPE" property="description" jdbcType="VARCHAR" />
        <result column="ACCOUNT_NUMBER" property="accountNumber"
            jdbcType="VARCHAR" />
        <result column="QUANTITY" property="shares" jdbcType="VARCHAR" />
        <result column="LONG_DESC" property="transDesc" jdbcType="VARCHAR" />
        <result column="PORT_NUM" property="indicator" jdbcType="INTEGER" />
        <result column="AMOUNT" property="amount" jdbcType="VARCHAR" />
    </resultMap>
</mapper>

我使用的是 MyBatis 版本 3.0.4,我的 Oracle 驱动程序 jar 是 ojdbc14-10.2.0.3.0.jar

Procedure 的 IN 和 OUT 参数及其数据类型如下:

P_USER_INST           NUMBER        IN     
P_GROUP_ID            NUMBER        IN 
P_ENTITY_ID           CHAR          IN 
P_ENTITY_NAME         VARCHAR2 (30) IN   
P_START_DATE          DATE          IN      
P_END_DATE            DATE          IN     
P_ASSETCLASS          CHAR          IN        
P_TRAN_TYPE           CHAR          IN   
P_PRIMARY_ASSET_ID    VARCHAR2      IN        
P_TICKER              VARCHAR2      IN   
P_ACCOUNT_DETAIL_CUR  REF CURSOR    OUT    

我在 Java 中的 DTO 如下(省略了 setter/getter 方法)

private Integer userInstance;

private Integer accountGroupId;

private String accountId;

private Date startDate;

private Date endDate;

private String transactionType;

private String ticker;

private String cusipId;

private String assetClass;

private List<AccountActivity> domainList;

任何帮助都将受到高度赞赏,因为我对正在发生的事情一无所知并且真的坚持这一点。

4

6 回答 6

4

我刚刚遇到了.net 而不是 Java 的类似问题。

我的问题与游标基于全局临时表打开的事实有关。当我们将 GTT 从“删除行”更改为“提交时保留行”时,它工作正常。

看看这对你有用吗?

于 2011-06-15T05:24:43.633 回答
0

这可能是表或数据文件中的物理或逻辑损坏。请与您的 DBA 联系以恢复数据。您可以在http://24x7dba.blogspot.com/2011/08/salvage-data-from-corrupted-oracle.html找到有关如何从 Oracle 表中恢复损坏数据的步骤

于 2011-08-02T13:35:50.277 回答
0

创建全局临时表时,如下所示。

CREATE GLOBAL TEMPORARY TABLE table_name(col-1 type, col-2 type, ...) ON COMMIT PRESERVE ROWS

于 2020-02-27T06:46:50.160 回答
0

就我而言,此错误与全局临时表有关。在 DDL 表中,我将“提交时删除行”更改为“提交时保留行”,问题已得到解决。

于 2019-09-25T14:05:30.387 回答
0

经过一周的努力,我终于解决了这个问题:

解决方案:游标很可能是基于全局临时表 (GTT) 打开的,该临时表是使用 ON COMMIT DELETE ROWS 选项创建的。ORA-08103:对象不再存在错误的原因是紧跟在删除语句之后的提交语句。DBA 团队不同意将 GTT 更改为提交保留行,所以最后我在 Java 服务层中添加了代码库[实现 Spring - 程序化事务]

package com.test;

import java.util.List;
import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class StudentJDBCTemplate implements StudentDAO {
   private DataSource dataSource;
   private JdbcTemplate jdbcTemplateObject;
   private PlatformTransactionManager transactionManager;

   public void setDataSource(DataSource dataSource) {
      this.dataSource = dataSource;
      this.jdbcTemplateObject = new JdbcTemplate(dataSource);
   }
   public void setTransactionManager(PlatformTransactionManager transactionManager) {
      this.transactionManager = transactionManager;
   }
   public void create(String name, Integer age, Integer marks, Integer year){
      TransactionDefinition def = new DefaultTransactionDefinition();
      TransactionStatus status = transactionManager.getTransaction(def);

      try {
         String SQL1 = "insert into Student (name, age) values (?, ?)";
         jdbcTemplateObject.update( SQL1, name, age);

         // Get the latest student id to be used in Marks table
         String SQL2 = "select max(id) from Student";
         int sid = jdbcTemplateObject.queryForInt( SQL2 );

         String SQL3 = "insert into Marks(sid, marks, year) " + "values (?, ?, ?)";
         jdbcTemplateObject.update( SQL3, sid, marks, year);

         System.out.println("Created Name = " + name + ", Age = " + age);
         transactionManager.commit(status);
      } 
      catch (DataAccessException e) {
         System.out.println("Error in creating record, rolling back");
         transactionManager.rollback(status);
         throw e;
      }
      return;
   }
   public List<StudentMarks> listStudents() {
      String SQL = "select * from Student, Marks where Student.id=Marks.sid";
      List <StudentMarks> studentMarks = jdbcTemplateObject.query(SQL, 
         new StudentMarksMapper());

      return studentMarks;
   }
}
于 2017-11-16T20:13:33.397 回答
0

ORA-8103“对象不再存在”

错误:ORA 8103

文本:对象不再存在

原因:自操作开始后,该对象已被其他用户删除。行动:删除对对象的引用。

ORA-8103 报告 SQL 语句发现一个不再属于该语句中引用的对象的块。原因 ORA-8103 是由无效的块类型引起的。区块头的区块类型无效或区块内的区块类型不是预期的;例如,预期数据块(类型=6),但实际块信息不是数据块(类型!=6)。ORA-8103 也是由意外的 data_object_id 引起的,其中涉及的对象在执行受影响的 SQL 语句时正在更改。

于 2016-02-22T08:48:04.580 回答