ORA-01001无效游标

时间:2013-06-13 07:46:32

标签: oracle plsql

我有一个“ORA-01001 invalid cursor”问题我无法解决。 在我们的生产环境中,我们有三个应用程序服务器,它指向单个数据库( Oracle 10g )。

我通过jdbc调用以下程序时收到“ora-01001无效游标”错误,

步骤:

CREATE OR REPLACE
PROCEDURE "GET_CUSTOMER_DETAILS"(
    p_ACC_NUM IN VARCHAR2 ,
    o_PRODUCT_CODE OUT VARCHAR2 ,
    o_PRODUCT_TYPE OUT VARCHAR2 ,
    o_NATIONALITY OUT VARCHAR2 ,
    o_CUSTOMER_CAT OUT VARCHAR2 ,
    o_SERVICE_STATUS OUT VARCHAR2 ,
    o_CURR_PLAN OUT VARCHAR2 ,
    o_ERROR_CODE OUT NUMBER ,
    o_ERROR_MSG OUT VARCHAR2 )
AS
  v_count         INT;
  v_accNum        VARCHAR2(50);
  v_Product_Desc  VARCHAR2(50);
  v_IPhone_Status VARCHAR2(50);
  v_BB_Status     VARCHAR2(50);
  v_now           DATE;
BEGIN
  o_CURR_PLAN := 0;
  SELECT PRODUCT_DESC,
    PRODUCT_NAME,
    IPHONE_STATUS,
    BB_STATUS,
    PARTY_NATIONALITY,
    CUSTOMER_CAT,
    SERVICE_STATUS,
    new_postpaid_flag
  INTO v_Product_Desc,
    o_PRODUCT_TYPE,
    v_IPhone_Status,
    v_BB_Status,
    o_NATIONALITY,
    o_CUSTOMER_CAT,
    o_SERVICE_STATUS,
    o_CURR_PLAN
  FROM tbl_crm_custmaster
  WHERE account_number  = p_ACC_NUM
  AND rownum            = 1;
  IF (v_Product_Desc    = 'WS' AND v_IPhone_Status = 'N' AND v_BB_Status = 'N') THEN
    o_PRODUCT_CODE     := 'WP'; --General Prepaid
  elsif (v_Product_Desc = 'WS' AND v_IPhone_Status = 'N' AND v_BB_Status = 'Y') THEN
    o_PRODUCT_CODE     := 'WB'; --BlackBerry Prepaid
  elsif (v_Product_Desc = 'WS' AND v_IPhone_Status = 'Y' AND v_BB_Status = 'N') THEN
    o_PRODUCT_CODE     := 'WI'; --IPhone Prepaid
  elsif (v_Product_Desc = 'WS' AND v_IPhone_Status = 'Y' AND v_BB_Status = 'Y') THEN
    o_PRODUCT_CODE     := 'WP'; --General Prepaid
  elsif (v_Product_Desc = 'GS' AND v_IPhone_Status = 'N' AND v_BB_Status = 'N') THEN
    o_PRODUCT_CODE     := 'GP'; --General Postpaid
  elsif (v_Product_Desc = 'GS' AND v_IPhone_Status = 'N' AND v_BB_Status = 'Y') THEN
    o_PRODUCT_CODE     := 'GB'; --BlackBerry Postpaid
  elsif (v_Product_Desc = 'GS' AND v_IPhone_Status = 'Y' AND v_BB_Status = 'N') THEN
    o_PRODUCT_CODE     := 'GI'; --IPhone Postpaid
  elsif (v_Product_Desc = 'GS' AND v_IPhone_Status = 'Y' AND v_BB_Status = 'Y') THEN
    o_PRODUCT_CODE     := 'GP'; --General Postpaid
  elsif (v_Product_Desc = '2P' OR v_Product_Desc = '3P') THEN
    o_PRODUCT_CODE     := 'EL'; --Landline associated with E-Life
  elsif (v_Product_Desc = 'VO') THEN
    o_PRODUCT_CODE     := 'GL'; --Landline Postpaid
  elsif (v_Product_Desc = 'FN') THEN
    o_PRODUCT_CODE     := 'WL'; --Landline Prepaid
  elsif (v_Product_Desc = 'HI') THEN
    o_PRODUCT_CODE     := 'IN'; --Landline Prepaid
  elsif (v_Product_Desc = 'EV') THEN
    o_PRODUCT_CODE     := 'EV'; --Landline Prepaid
  END IF;
  o_ERROR_CODE := 0;
  o_ERROR_MSG  := 'SUCCESS';
EXCEPTION
WHEN NO_DATA_FOUND THEN
  o_ERROR_CODE := -1;
  o_ERROR_MSG  := 'NO REOCRDS FOUND';
WHEN OTHERS THEN
  o_ERROR_CODE := SQLCODE;
  o_ERROR_MSG  := SQLERRM;
END;

Java代码1:

public void requestBegin(SCESession mySession) {
        // TODO Auto-generated method stub

        ITraceInfo trace = mySession.getTraceOutput();
        UserDetails userDetails  = (UserDetails) mySession.getProperty(EtisalatConstants.USER_DETAILS);
        CallDetailsBean detailsBean=(CallDetailsBean) mySession.getProperty(EtisalatConstants.CALLER_DETAILS_BEAN_OBJECT);
        DwhEtisalatMethods etisalatMethods=null;
        HashMap<String, String> response = new HashMap<String, String>();
        String hostErrResponse = "", hostErrCode = "";
        EtaDbImpl dao = null;
        try{
            //Host Reporting Start Details
            etisalatMethods=new DwhEtisalatMethods();
            etisalatMethods.HostStartDetails(mySession, CommonMethod.generateUniqueId(), LoggingConstants.GET_CALLER_DETAILS_CRM, LoggingConstants.NOT_APPLICABLE, LoggingConstants.DATABASE);

            dao = new EtaDbImpl();
            response = dao.getCustomerDetails(userDetails.getPhoneNumber(), mySession);
            trace.writeln(ITraceInfo.TRACE_LEVEL_DEBUG,"DB Success:");


            hostErrCode = response.get(EtisalatDbConstants.ERROR_CODE);
            hostErrResponse = response.get(EtisalatDbConstants.ERROR_MSG);
            trace.writeln(ITraceInfo.TRACE_LEVEL_DEBUG,"ERROR_CODE:"+hostErrCode);
            trace.writeln(ITraceInfo.TRACE_LEVEL_DEBUG,"ERROR_Response:"+hostErrResponse);


            if(hostErrResponse.equalsIgnoreCase(EtisalatDbConstants.DB_SUCCESS_MSG) || hostErrCode.equalsIgnoreCase(EtisalatDbConstants.DB_SUCCESS_CODE)){
            userDetails.setAccountNumber(response.get(EtisalatDbConstants.ACCOUNT_NUMBER));
            //userDetails.setPhoneNumber(response.get(EtisalatDbConstants.PHONE_NUMBER));
            userDetails.setProductType(response.get(EtisalatDbConstants.PRODUCT_TYPE));
            userDetails.setProductCode(response.get(EtisalatDbConstants.PROD_CODE));
            userDetails.setNationality(response.get(EtisalatDbConstants.NATIONALITY));
            userDetails.setCustomerCategory(response.get(EtisalatDbConstants.CUSTOMER_CAT));
            userDetails.setCurrPlan(response.get(EtisalatDbConstants.CURR_PLAN));
            userDetails.setServiceStatus(response.get(EtisalatDbConstants.SERVICE_STATUS));



            //Set in Project variable
            mySession.getVariableField(IProjectVariables.APP_VARIABLES, IProjectVariables.APP_VARIABLES_FIELD_ACCOUNT_NO).setValue(userDetails.getAccountNumber());
            mySession.getVariableField(IProjectVariables.APP_VARIABLES, IProjectVariables.APP_VARIABLES_FIELD_PRODUCT_CODE).setValue(userDetails.getProductCode());
            mySession.getVariableField(IProjectVariables.APP_VARIABLES, IProjectVariables.APP_VARIABLES_FIELD_PRODUCT_TYPE).setValue(userDetails.getProductType());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_ACCT_NO).setValue(userDetails.getAccountNumber());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_CUSTOMER_CATEGORY).setValue(userDetails.getCustomerCategory());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_NATIONALITY).setValue(userDetails.getNationality());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_PRODUCT_CODE).setValue(userDetails.getProductCode());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_PRODUCT_TYPE).setValue(userDetails.getProductType());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_SERVICE_STATUS).setValue(userDetails.getServiceStatus());
            mySession.getVariableField(IProjectVariables.GET_CRMCUST_MASTER, IProjectVariables.GET_CRMCUST_MASTER_FIELD_CURR_PLAN).setValue(userDetails.getCurrPlan());


            detailsBean.setAuthenticated_Type(userDetails.getProductType());
            detailsBean.setAuthenticated_number(userDetails.getAccountNumber());
            mySession.getVariableField(IProjectVariables.FLAGS, IProjectVariables.FLAGS_FIELD_HOSTSERVICE_STATUS).setValue(EtisalatConstants.YES);
            detailsBean.setCaller_authenticated(EtisalatConstants.REPORT_YES);

            //Setting the customer segment for reporting purpose
            detailsBean.setCustomer_segment(userDetails.getCustomerSegment());

            //Setting the available products for the caller
            //detailsBean.setProduct_category(userDetails.getProductType());
            detailsBean.setProduct_category(userDetails.getProductCode());

            detailsBean.setAccount_number(userDetails.getAccountNumber());
            detailsBean.setAuthenticated_number(userDetails.getAccountNumber());
            detailsBean.setAuthenticated_Type("AUTO");
            }else if(hostErrResponse.equalsIgnoreCase(EtisalatDbConstants.DB_NO_REC_MSG) || hostErrCode.equalsIgnoreCase(EtisalatDbConstants.DB_NO_REC_CODE)){
                mySession.getVariableField(IProjectVariables.FLAGS, IProjectVariables.FLAGS_FIELD_HOSTSERVICE_STATUS).setValue(EtisalatConstants.NO);
                trace.writeln(ITraceInfo.TRACE_LEVEL_ERROR, "No Record Found for the account_number of '"+userDetails.getPhoneNumber()+"'");
            }else{
                throw new Exception(hostErrResponse); //Line No: 185
            }


        }catch (Exception e) {
            // TODO Auto-generated catch block
            detailsBean.setCall_end_reason(EtisalatConstants.CALLEND_REASON_DBDOWN);
            mySession.getVariableField(IProjectVariables.FLAGS, IProjectVariables.FLAGS_FIELD_HOSTSERVICE_STATUS).setValue(EtisalatConstants.NO);
            trace.writeln(ITraceInfo.TRACE_LEVEL_ERROR, "Exception : There is an issue while getting customer details "+e);
            e.printStackTrace();
        }finally{
            mySession.setProperty(EtisalatConstants.USER_DETAILS, userDetails);
            mySession.setProperty(EtisalatConstants.CALLER_DETAILS_BEAN_OBJECT, detailsBean);

            //Host Reporting End Details
            etisalatMethods.HostEndDetails(mySession, LoggingConstants.NOT_APPLICABLE, LoggingConstants.NOT_APPLICABLE, LoggingConstants.NOT_APPLICABLE, hostErrResponse, LoggingConstants.NOT_APPLICABLE);

            response = null;
            etisalatMethods=null;
            hostErrResponse = null;
            detailsBean = null;
            trace = null;
            userDetails = null;
            dao = null;
        }
        super.requestBegin(mySession);
    }

Java代码2:

public HashMap<String, String> getCustomerDetails(String acctNo, SCESession mySession){
  ITraceInfo trace = mySession.getTraceOutput();
  dataSource = (BasicDataSource)mySession.getProperty(DATASRC_IVR_DB);

  HashMap<String, String> returnhash = new HashMap<String, String>();
  //trace.writeln(ITraceInfo.TRACE_LEVEL_INFO, "Account number :"+acctNo.substring(acctNo.length()-4) );
  try
  {
  //logger.debug(callId+" The input is:"+hm);
  start=System.currentTimeMillis();
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO, "Start Time of GET_CUSTOMER_DETAILS="+start);

  con=dataSource.getConnection();
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO, "Data source connection established");
  proc = con.prepareCall("{ call GET_CUSTOMER_DETAILS(?, ?, ?, ?, ?, ?, ?, ?, ?) }");


  if(acctNo !=null && !acctNo.trim().isEmpty()){
  proc.setString(1, acctNo);
  }else{
  proc.setNull(1,  OracleTypes.VARCHAR);
  }

  proc.registerOutParameter(2, Types.VARCHAR);
  proc.registerOutParameter(3, Types.VARCHAR);
  proc.registerOutParameter(4, Types.VARCHAR);
  proc.registerOutParameter(5, Types.VARCHAR);
  proc.registerOutParameter(6, Types.VARCHAR);
  proc.registerOutParameter(7, Types.VARCHAR);
  proc.registerOutParameter(8, Types.INTEGER);
  proc.registerOutParameter(9, Types.VARCHAR);
  try {
  if(!QueryTimeout.equalsIgnoreCase(NO))
  proc.setQueryTimeout(Integer.parseInt(QueryTimeout));
  else
  proc.setQueryTimeout(_2s);
  } catch (NumberFormatException e) {
  proc.setQueryTimeout(_2s);
  }
  trace.writeln(ITraceInfo.TRACE_LEVEL_DEBUG,"Time out="+QueryTimeout);
  proc.execute();

  returnhash.put(ERROR_CODE, proc.getString(8));
  returnhash.put(ERROR_MSG, proc.getString(9));

  if(returnhash.get(ERROR_MSG).equalsIgnoreCase(DB_SUCCESS_MSG) || returnhash.get(ERROR_CODE).equalsIgnoreCase(DB_SUCCESS_CODE)){

  returnhash.put(ACCOUNT_NUMBER, acctNo);
  //returnhash.put(PHONE_NUMBER, rs.getString(2));
  returnhash.put(PROD_CODE, proc.getString(2));
  returnhash.put(PRODUCT_TYPE, proc.getString(3));
  returnhash.put(NATIONALITY, proc.getString(4));
  returnhash.put(CUSTOMER_CAT, proc.getString(5));
  returnhash.put(SERVICE_STATUS, proc.getString(6));
  returnhash.put(CURR_PLAN, proc.getString(7));


  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,ACCOUNT_NUMBER+":"+ acctNo);
trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,PROD_CODE+":" + proc.getString(2));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,PRODUCT_TYPE+":" + proc.getString(3));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,NATIONALITY+":" + proc.getString(4));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,CUSTOMER_CAT+":" + proc.getString(5));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,SERVICE_STATUS+":" + proc.getString(6));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,CURR_PLAN+":" + proc.getString(7));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,ERROR_CODE+":"+proc.getString(8));
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO,ERROR_MSG+":"+proc.getString(9));
  }else{
  trace.writeln(ITraceInfo.TRACE_LEVEL_DEBUG, "No records found");
  }
  end=System.currentTimeMillis();
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO, "end Time of GET_CUSTOMER_DETAILS="+end);
  trace.writeln(ITraceInfo.TRACE_LEVEL_INFO, "Total Time of GET_CUSTOMER_DETAILS="+(end-start)+"ms");
  }
  catch (SQLException e)
  {
  returnhash.put(ERROR_CODE, "03");
  returnhash.put(ERROR_MSG, e.getMessage());
  trace.writeln(ITraceInfo.TRACE_LEVEL_ERROR, "SQL Exception"+e);
  e.printStackTrace();
  }
  finally{
  try{
  closeResult(rs);
  closeCallableStmt(proc);
  closeConnection(con);
  }catch(SQLException e){
  returnhash.put(ERROR_CODE, "03");
  returnhash.put(ERROR_MSG, e.getMessage());
  trace.writeln(ITraceInfo.TRACE_LEVEL_ERROR, "SQL Exception while closing the Connection "+e);
  }
  if(trace != null){
  trace = null;
  }
  if(dataSource != null){
  dataSource = null;
  }
  }
  return returnhash;
  }

Java代码1方法调用Java代码2方法。 在java Code 1中,我正在处理从oracle接收的数据。 在java代码2中,我正在调用存储过程。

我在过程级别处理了sql异常。如果过程中有任何错误,则该过程将oracle错误代码和错误消息作为参数返回。在java Code 2中,我收到oracle错误代码(1001)并将其存储在hashmap中,之后我检查错误代码是否等于0(成功)。因此,它不打印任何reocrd日志。在java Code 1中,我收到了hashmap。从hashmap中,我取出了错误代码值。如果错误代码不等于0或-1,那么我将抛出从oracle收到的异常(打印在跟踪日志和堆栈跟踪日志中)。

跟踪记录

12/06/2013 06:26:35:063  INFO - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : Start Time of GET_CUSTOMER_DETAILS=1371003995063
12/06/2013 06:26:35:065  INFO - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : Data source connection established
12/06/2013 06:26:35:065 DEBUG - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : Time out=2
12/06/2013 06:26:35:067 DEBUG - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : No records found
12/06/2013 06:26:35:067  INFO - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : end Time of GET_CUSTOMER_DETAILS=1371003995067
12/06/2013 06:26:35:067  INFO - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : Total Time of GET_CUSTOMER_DETAILS=4ms
12/06/2013 06:26:35:067 DEBUG - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : DB Success:
12/06/2013 06:26:35:067 DEBUG - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : ERROR_CODE:-1001
12/06/2013 06:26:35:067 DEBUG - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : ERROR_Response:ORA-01001: invalid cursor
12/06/2013 06:26:35:067 ERROR - EC2E4987556A7FF7DA6DEE8EEE9843FC.jvm2:/ETA_MAIN : Exception : There is an issue while getting customer details java.lang.Exception: ORA-01001: invalid cursor

堆栈跟踪日志:

 java.lang.Exception: ORA-01001: invalid cursor
at flow.DB_GetCRM_CustMaster.requestBegin(DB_GetCRM_CustMaster.java:185)
at com.avaya.sce.runtime.AppServlet.processRequest(AppServlet.java:81)
at com.avaya.sce.runtime.SCEServlet.requestHandler(SCEServlet.java:282)
at com.avaya.sce.runtime.SCEServlet.doPost(SCEServlet.java:189)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at com.avaya.sce.runtime.SCEServlet.forward(SCEServlet.java:1303)
at com.avaya.sce.runtime.Data.evaluateActions(Data.java:211)
at flow.DB_GetCallerProfileDetails.executeDataActions(DB_GetCallerProfileDetails.java:94)

我无法在SQLPlus中重现此问题,它只发生在来自应用服务器2和应用服务器3的jdbc次调用中,并且重复相同的调用通常有效(但有时会失败几次)成功之前的时间)。我没有在程序中使用任何光标。请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

也许类型不正确..你可以将签名更改为:

CREATE OR REPLACE PROCEDURE "GET_CUSTOMER_DETAILS"(
    p_ACC_NUM IN VARCHAR2 ,
    o_PRODUCT_CODE OUT VARCHAR2 ,
    o_PRODUCT_TYPE OUT tbl_crm_custmaster.PRODUCT_NAME%type,
    o_NATIONALITY OUT tbl_crm_custmaster.PARTY_NATIONALITY%type ,
    o_CUSTOMER_CAT OUT tbl_crm_custmaster.CUSTOMER_CAT%type ,
    o_SERVICE_STATUS OUT tbl_crm_custmaster.SERVICE_STATUS%type ,
    o_CURR_PLAN OUT tbl_crm_custmaster.new_postpaid_flag%type,
    o_ERROR_CODE OUT NUMBER ,
    o_ERROR_MSG OUT VARCHAR2 ) AS
    v_count         INT;
    v_accNum        VARCHAR2(50);
    v_Product_Desc  tbl_crm_custmaster.PRODUCT_DESC%type,
    v_IPhone_Status tbl_crm_custmaster.IPHONE_STATUS%type;
    v_BB_Status     tbl_crm_custmaster.BB_STATUS%type;
    v_now           DATE;