简体   繁体   中英

MyBatis Oracle Call PLS-00306: wrong number or types of arguments in call Error

I'm trying to call to a PL/SQL stored procedure from MyBatis.

I'd try several options and configurations for the Select Callable statement type, but I'm block on this error.

I have this configurations / files:

The PL/SQL Method:

PROCEDURE re_pr_ins_apunte_ref ( p_seqrec     IN   RE_T_GE_RECEPTIVO.seq_rec%TYPE,
                             p_seqres     IN   NUMBER,
                             p_importe    IN   NUMBER,
                             p_divisa     IN   gn_t_divisa.cod_divisa%TYPE, 
                             p_codref     IN   RE_T_AD_LIBRO_AGENCIA.cod_referencia_pago%TYPE, 
                             p_codest     IN   RE_T_CD_ESTADO_COBRO.cod_estado%TYPE,
                             p_codpas     IN   RE_T_CD_ESTADO_COBRO.cod_pasarela%TYPE,
                             po_ok        OUT  BOOLEAN, 
                             po_error     OUT  VARCHAR2,  
                             p_autonomous IN   BOOLEAN := TRUE,                                  p_merchant_id IN RE_T_AD_LIBRO_AGENCIA.merchant_id%TYPE DEFAULT NULL
                          ) IS

XML MyBatis Repository select operation:

<select id="agencyBookPostingLineInsRefCall"
            parameterType="com.hotelbeds.commonbookingservice.entity.confirmation.agencybookpostingline.AgencyBookPostingLineInsIOWrapper"
            statementType="CALLABLE">
        {call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref(
             #{wrapper.incomingOfficeId,  mode=IN,    jdbcType=INTEGER} => P_SEQREC
            , #{wrapper.bookingNumber,    mode=IN,    jdbcType=INTEGER} => P_SEQRES
            , #{wrapper.amount,           mode=IN,    jdbcType=NUMERIC} => P_IMPORTE
            , #{wrapper.currencyId,       mode=IN,    jdbcType=VARCHAR} => P_DIVISA
            , #{wrapper.referenceCode,    mode=IN,    jdbcType=VARCHAR} => P_CODREF
            , #{wrapper.paymentStatus,    mode=IN,    jdbcType=VARCHAR} => P_CODEST
            , #{wrapper.paymentGatewayId, mode=IN,    jdbcType=VARCHAR} => P_CODPAS
            , #{wrapper.ok,               mode=OUT,   jdbcType=VARCHAR, typeHandler=com.hotelbeds.commonbookingservice.db.handler.BooleanTrueFalseTypeHandler}
=> PO_OK
            , #{wrapper.error,            mode=OUT,   jdbcType=VARCHAR }
=> PO_ERROR
            , #{wrapper.autonomous,       mode=IN,    jdbcType=VARCHAR, typeHandler=com.hotelbeds.commonbookingservice.db.handler.BooleanTrueFalseTypeHandler}
=> P_AUTONOMOUS
            , #{wrapper.merchantId,       mode=IN,    jdbcType=VARCHAR} => P_MERCHANT_ID
            )
        }
    </select>

Method in interface class

[...]

void agencyBookPostingLineInsRefCall(@Param("wrapper") AgencyBookPostingLineInsIOWrapper wrapper);

[...]

The Wrapper Class for parameters:

/**
 * Wrapper for the method AgencyBookPostingLineIns
 */
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
public class AgencyBookPostingLineInsIOWrapper implements Serializable {

/** The Constant serialVersionUID. */
private static final long serialVersionUID = -6621442227563572393L;

/** Input */
private Integer incomingOfficeId;
private Integer bookingNumber;
private BigDecimal amount;
private String currencyId;
private String referenceCode;
private String paymentStatus;
private String paymentGatewayId;
private Boolean autonomous;
private String merchantId;

/** Output */
private Boolean ok;
private String error;

Boolean Type Handler:

/**
 * Example with values true,false to boolean Handler.
 */
@MappedTypes(Boolean.class)
public class BooleanTrueFalseTypeHandler extends AbstractBooleanTypeHandler {



    /** The Constant FALSE_STRING. */
    private static final String FALSE_STRING = "false";

    /** The Constant TRUE_STRING. */
    private static final String TRUE_STRING = "true";

    /**
     * The constructor
     */
    public BooleanTrueFalseTypeHandler() {
        super();
        falseString = FALSE_STRING;
        trueString = TRUE_STRING;
    }
}

And The error:

==>  Preparing: {call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref( ? => P_SEQREC , ? => P_SEQRES , ? => P_IMPORTE , ? => P_DIVISA , ? => P_CODREF , ? => P_CODEST , ? => P_CODPAS , ? => PO_OK , ? => PO_ERROR , ? => P_AUTONOMOUS , ? => P_MERCHANT_ID ) } 
==> Parameters: 1(Integer), 3527758(Integer), 200(BigDecimal), EUR(String), 051609100(String), T(String), BIB(String), true(String), MERCHAN(String)
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored

### The error may exist in com/hotelbeds/commonbookingservice/db/repository/booking/BookingReconfirmationRepository.xml
### The error may involve com.hotelbeds.commonbookingservice.db.repository.booking.BookingReconfirmationRepository.agencyBookPostingLineInsRefCall-Inline
### The error occurred while setting parameters
### SQL: {call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref(              ? => P_SEQREC             , ? => P_SEQRES             , ? => P_IMPORTE             , ? => P_DIVISA             , ? => P_CODREF             , ? => P_CODEST             , ? => P_CODPAS             , ? => PO_OK             , ? => PO_ERROR             , ? => P_AUTONOMOUS             , ? => P_MERCHANT_ID             )         }
### Cause: java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored

; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored

I thing the problem is related with the 2 OUT parameters.

The problem is suppoused to be because of the stored procedure BOOLEAN out parameter:

  • po_ok OUT BOOLEAN.

There is a known problem with PL/SQL BOOLEANS in ORACLE Jdbc.

http://docs.oracle.com/cd/A87861_01/NT817EE/java.817/a83723/typesup1.htm


Wrapping PL/SQL BOOLEAN, RECORD, and TABLE Types

Oracle JDBC drivers do not support calling arguments or return values of the PL/SQL types TABLE (now known as indexed-by tables), RECORD, or BOOLEAN.

As a workaround, you can create wrapper procedures that handle the data as types supported by JDBC. For example, to wrap a stored procedure that uses PL/SQL booleans, you can create a stored procedure that takes a character or number from JDBC and passes it to the original procedure as BOOLEAN, or, for an output parameter, accepts a BOOLEAN argument from the original procedure and passes it as a CHAR or NUMBER to JDBC. Similarly, to wrap a stored procedure that uses PL/SQL records, you can create a stored procedure that handles a record in its individual components (such as CHAR and NUMBER). To wrap a stored procedure that uses PL/SQL tables, you can break the data into components or perhaps use Oracle collection types.

I've had to implement a PL/SQL wrapper procedure that check de BOOLEAN value and which returns a VARCHAR to Java with jdbc connector.

PROCEDURE re_pr_ins_apunte_ref_w ( p_seqrec     IN   RE_T_GE_RECEPTIVO.seq_rec%TYPE, -- Oficina que gestiona el apunte
                                  p_seqres     IN   NUMBER,  -- Reserva
                                 p_importe    IN   NUMBER, -- Importe Haber.
                                 p_divisa     IN   gn_t_divisa.cod_divisa%TYPE, 
                                 p_codref     IN   RE_T_AD_LIBRO_AGENCIA.cod_referencia_pago%TYPE, -- Referencia de pago.
                                 p_codest     IN   RE_T_CD_ESTADO_COBRO.cod_estado%TYPE,
                                 p_codpas     IN   RE_T_CD_ESTADO_COBRO.cod_pasarela%TYPE,
                                 po_ok        OUT VARCHAR2,                -- Indica si la funcion ha terminado correctamente
                                 po_error     OUT VARCHAR2,
                                 p_autonomous IN  BOOLEAN := TRUE,            -- True: Nextval, False: Nextval_no_autonomous
                                 p_merchant_id IN RE_T_AD_LIBRO_AGENCIA.merchant_id%TYPE DEFAULT NULL

                              ) IS

    vo_ok  BOOLEAN; 

BEGIN

re_pr_ins_apunte_ref(   p_seqrec, -- Oficina que gestiona el apunte
                        p_seqres, -- Secuencia de la venta (seq_reserva, seq_cargo, seq_expediente, seq_contr)
                        p_importe, -- Importe Haber.
                        p_DIVISA, -- Divisa en la que está expresado el importe
                        p_codref, -- Referencia de pago.
                        p_codest,
                        p_codpas,
                        vo_ok,  -- Indica si la funcion ha terminado correctamente
                        po_error,  -- Descripcion del error
                        p_autonomous, -- True: Nextval, False: Nextval_no_autonomous
                        p_merchant_id);

IF (VO_OK) THEN 
    po_ok := 'S';
  ELSE
    po_ok := 'N';
  END IF;

END re_pr_ins_apunte_ref_w;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM