Getting PSQLException while calling a Stored Procedure (which inserts record into lsa_user_info table) from Java method ( which is in DAO Layer)

回眸只為那壹抹淺笑 提交于 2021-02-11 13:46:57

问题


I am new to stored procedures. I want to insert a record with 20 column values into lsa_user_info table. I am invoking a stored procedure to do this task.

Also, I'm expecting the resultset will return the primary key value of the record that was inserted (user_id). But, I'm getting this error instead:

org.postgresql.util.PSQLException: **The column index is out of range: 20, number of columns: 19.

lsa_user_info table definition :

CREATE TABLE public.lsa_user_info
(
        user_id integer NOT NULL DEFAULT nextval('lsa_user_info_user_id_seq'::regclass),
        created_datetime timestamp without time zone,
        created_user_id integer,
        email_id character varying(255),
        first_name character varying(255),
        last_name character varying(255),
        modified_datetime timestamp without time zone,
        modified_user_id integer,
        status_id integer,
        user_name character varying(255),
        user_timezone character varying,
        phone_extension character varying,
        phone_direct character varying(255),
        supervisor character varying(255),
        title character varying(255),
        fax character varying(255),
        preferred_name character varying(255),
        state character varying(255),
        supervisor_phone character varying(255),
        supervisor_extension character varying(255),
        loan_type character varying(255),
        investor_name character varying(255),
        language_indicator character varying(255),
        working_hrs character varying(255),
        group_id character varying(255),
        racfid character varying(255),
        uuid character varying(255),
        agent_type character varying(100),
        line_of_business integer DEFAULT 1,
        system_admin_flag boolean DEFAULT false,

        CONSTRAINT user_info_pkey PRIMARY KEY (user_id)
) WITH (OIDS=FALSE);

 ALTER TABLE public.lsa_user_info
    OWNER TO lsasdev;
     GRANT ALL ON TABLE public.lsa_user_info TO lsasdev;

This is my stored procedure:

CREATE OR REPLACE FUNCTION public.insert_user_info(
     email_id character varying, 
     first_name character varying,
     last_name character varying,
     modified_user_id integer,
     status_id integer, 
     user_name character varying, 
     user_timezone character varying, 
     phone_extension character varying, 
     phone_direct character varying, 
     supervisor character varying, 
     title character varying, 
     fax character varying, 
     preferred_name character varying,
     supervisor_phone character varying, 
     supervisor_extension character varying, 
     working_hrs character varying, 
     group_id character varying,
     line_of_business integer, 
     system_admin_flag boolean, 
     racfid character varying) RETURNS numeric 
AS
     $BODY
     BEGIN
           INSERT INTO public.lsa_user_info(
           email_id, first_name,last_name,
          modified_user_id, status_id, user_name, user_timezone,
         phone_extension, phone_direct, supervisor, title,  fax,
        preferred_name, supervisor_phone, supervisor_extension,  working_hrs, group_id, 
         line_of_business, system_admin_flag,racfid) VALUES

          ( email_id, first_name,last_name,
    modified_user_id, status_id, user_name, user_timezone,
         phone_extension, phone_direct, supervisor, title,  fax,
        preferred_name, supervisor_phone, supervisor_extension,  working_hrs, group_id, 
         line_of_business, system_admin_flag, racfid  );

   RETURN 1;
    END

$BODY$
    LANGUAGE plpgsql VOLATILE
 COST 100;
   ALTER FUNCTION public.insert_user_info(character varying, character varying, character varying, 
    integer, integer, character varying, character varying, character varying, character varying, 
   character varying, character varying, character varying, character varying, character varying, 
   character varying, character varying, character varying, integer, boolean, character varying)
  OWNER TO lsasdev;

This is my code invoking the stored procedure:

     public Integer invokeUserInfoStoredProc(UserInfoHibVO userInfoHibVO)throws Exception{
        log.info("********** Execcution of Stored Procedure insert_user_info() started ********");
                   ResultSet resultset =null;
           Connection connection =null;
         CallableStatement storedProcedure = null;
         BigDecimal resp =null;
         Session session = sessionFactory.getCurrentSession();
         SessionImpl sessionImpl = (SessionImpl) session;
         Integer generatedUserId = null;

         try {
            connection = sessionImpl.connection();          
            connection.setAutoCommit(false);
            log.info("Connection to LSAS DB established successfully.");
        
            storedProcedure = connection.prepareCall("{ ? = call 
        insert_user_info(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?}");
            storedProcedure.registerOutParameter(1, Types.NUMERIC);
        
            storedProcedure.setString(2,userInfoHibVO.getEmail());
            storedProcedure.setString(3,userInfoHibVO.getFirstName());
            storedProcedure.setString(4,userInfoHibVO.getLastName());
        
            storedProcedure.setInt(5,userInfoHibVO.getModifiedUserId()!=null ? userInfoHibVO.getModifiedUserId() : 0);
            storedProcedure.setInt(6,userInfoHibVO.getUserStatus().getStatusId());
            storedProcedure.setString(7,userInfoHibVO.getUsername());
            storedProcedure.setString(8,userInfoHibVO.getUserTimezone());
        
            storedProcedure.setString(9,StringUtil.isNotEmpty(userInfoHibVO.getPhoneExtension()) ? userInfoHibVO.getPhoneExtension():"");
            storedProcedure.setString(10,StringUtil.isNotEmpty(userInfoHibVO.getPhoneDirect()) ? userInfoHibVO.getPhoneDirect():"");
            storedProcedure.setString(11,StringUtil.isNotEmpty(userInfoHibVO.getManager()) ? userInfoHibVO.getManager():"");
            storedProcedure.setString(12,StringUtil.isNotEmpty(userInfoHibVO.getTitle()) ? userInfoHibVO.getTitle():"");
             storedProcedure.setString(13,StringUtil.isNotEmpty(userInfoHibVO.getFax()) ? userInfoHibVO.getFax():"");
        
        storedProcedure.setString(14,userInfoHibVO.getPreferredName());
        storedProcedure.setString(15,StringUtil.isNotEmpty(userInfoHibVO.getSupervisorPhone())?userInfoHibVO.getSupervisorPhone():"");
        storedProcedure.setString(16,userInfoHibVO.getSupervisorExtension());
        storedProcedure.setString(17,StringUtil.isNotEmpty(userInfoHibVO.getWorkingHrs())? userInfoHibVO.getWorkingHrs():"");
        storedProcedure.setString(18,StringUtil.isNotEmpty(userInfoHibVO.getGroup()) ? userInfoHibVO.getGroup():"");
        storedProcedure.setInt(19,userInfoHibVO.getLob());
        storedProcedure.setBoolean(20, false);
        storedProcedure.setString(21,"");

        storedProcedure.executeUpdate();

        resp = (BigDecimal) storedProcedure.getObject(1);
        resultset = storedProcedure.getGeneratedKeys();

        if(resultset!=null && resultset.next())
            generatedUserId= resultset.getInt(1);

        log.info("********** Stored Procedure insert_user_info() Executed successfully ********");
    }catch(Exception exp){
        exp.printStackTrace();
        log.error("Exception occurred in executing stored procedure for insert_user_info() data:" + exp);
    }finally{
        if(null!=resultset)resultset.close();
        if(null!=storedProcedure)storedProcedure.close();
        log.info("Stored proc insert_user_info() ended**************");
    }
                return generatedUserId;
} 

Please let me know what is the issue? Why I am getting this error:

The column index is out of range: 20, number of columns: 19.

Please assist me! Thanks in advance


回答1:


Changes in function: after inserting the data in table, the function should return the user_id of inserted row. you should change your Function as below

  1. Change the return type from Numeric to Bigint
  2. Change the name of parameters because table column names and parameter name are same.
  3. Use returning statement with insert into to return the inserted user_id

Code:

CREATE OR REPLACE FUNCTION PUBLIC.insert_user_info (
        param_email_id CHARACTER VARYING,
        param_first_name CHARACTER VARYING,
        param_last_name CHARACTER VARYING,
        param_modified_user_id INTEGER,
        param_status_id INTEGER,
        param_user_name CHARACTER VARYING,
        param_user_timezone CHARACTER VARYING,
        param_phone_extension CHARACTER VARYING,
        param_phone_direct CHARACTER VARYING,
        param_supervisor CHARACTER VARYING,
        param_title CHARACTER VARYING,
        param_fax CHARACTER VARYING,
        param_preferred_name CHARACTER VARYING,
        param_supervisor_phone CHARACTER VARYING,
        param_supervisor_extension CHARACTER VARYING,
        param_working_hrs CHARACTER VARYING,
        param_group_id CHARACTER VARYING,
        param_line_of_business INTEGER,
        param_system_admin_flag BOOLEAN,
        param_racfid CHARACTER VARYING 
    ) RETURNS BIGINT AS $BODY DECLARE
    x AS BIGINT BEGIN
        x = (
            INSERT INTO PUBLIC.lsa_user_info (
                email_id,
                first_name,
                last_name,
                modified_user_id,
                status_id,
                user_name,
                user_timezone,
                phone_extension,
                phone_direct,
                supervisor,
                title,
                fax,
                preferred_name,
                supervisor_phone,
                supervisor_extension,
                working_hrs,
                group_id,
                line_of_business,
                system_admin_flag,
                racfid 
            )
        VALUES
            (
                param_email_id,
                param_first_name,
                param_last_name,
                param_modified_user_id,
                param_status_id,
                param_user_name,
                param_user_timezone,
                param_phone_extension,
                param_phone_direct,
                param_supervisor,
                param_title,
                param_fax,
                param_preferred_name,
                param_supervisor_phone,
                param_supervisor_extension,
                param_working_hrs,
                param_group_id,
                param_line_of_business,
                param_system_admin_flag,
                param_racfid 
            ) RETURNING user_id;
        
    ) RETURN x;

END $BODY$ LANGUAGE plpgsql VOLATILE COST 100;

Changes in JAVA code: In Java code calling of Postgres function is different from stored procedure of MySQL or Oracle.

public Integer invokeUserInfoStoredProc(UserInfoHibVO userInfoHibVO)throws Exception{
        log.info("********** Execution of stored procedure insert_user_info() started ********");
        ResultSet resultset =null;
        Connection connection =null;
        Long resp =null;
        Session session = sessionFactory.getCurrentSession();
        SessionImpl sessionImpl = (SessionImpl) session;
        Integer generatedUserId = null;

        try{
            connection = sessionImpl.connection();           
            connection.setAutoCommit(false);
            log.info("Connection to LSAS DB established successfully.");
            String SQL="select * from insert_user_info(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?}"
            PreparedStatement storedProcedure = connection.prepareStatement(SQL);
            storedProcedure.setString(1,userInfoHibVO.getEmail());
            storedProcedure.setString(2,userInfoHibVO.getFirstName());
            storedProcedure.setString(3,userInfoHibVO.getLastName());
            storedProcedure.setInt(4,userInfoHibVO.getModifiedUserId()!=null ? 
            userInfoHibVO.getModifiedUserId() : 0);
            storedProcedure.setInt(5,userInfoHibVO.getUserStatus().getStatusId());
            storedProcedure.setString(6,userInfoHibVO.getUsername());
            storedProcedure.setString(7,userInfoHibVO.getUserTimezone());
            storedProcedure.setString(8,StringUtil.isNotEmpty(userInfoHibVO.getPhoneExtension()) ? 
            userInfoHibVO.getPhoneExtension():"");
            storedProcedure.setString(9,StringUtil.isNotEmpty(userInfoHibVO.getPhoneDirect())? 
            userInfoHibVO.getPhoneDirect():"");
            storedProcedure.setString(10,StringUtil.isNotEmpty(userInfoHibVO.getManager())? 
            userInfoHibVO.getManager():"");
            storedProcedure.setString(11,StringUtil.isNotEmpty(userInfoHibVO.getTitle())? 
            userInfoHibVO.getTitle():"");
            storedProcedure.setString(12,StringUtil.isNotEmpty(userInfoHibVO.getFax())? 
            userInfoHibVO.getFax():"");
            storedProcedure.setString(13,userInfoHibVO.getPreferredName());
            storedProcedure.setString(14,StringUtil.isNotEmpty(userInfoHibVO.getSupervisorPhone())?userInfoHibVO.getSupervisorPhone():"");
            storedProcedure.setString(15,userInfoHibVO.getSupervisorExtension());
            storedProcedure.setString(16,StringUtil.isNotEmpty(userInfoHibVO.getWorkingHrs())? 
            userInfoHibVO.getWorkingHrs():"");
            storedProcedure.setString(17,StringUtil.isNotEmpty(userInfoHibVO.getGroup())? 
            userInfoHibVO.getGroup():"");
            storedProcedure.setInt(18,userInfoHibVO.getLob());
            storedProcedure.setBoolean(19, false);
            storedProcedure.setString(20,"");

            resultset = storedProcedure.executeQuery();

            if(resultset!=null && resultset.next())
                generatedUserId= resultset.getLong(0);
            log.info("********** Stored Procedure insert_user_info() Executed successfully ********");
        }
        catch(Exception exp){
            exp.printStackTrace();
            log.error("Exception occurred in executing stored procedure for insert_user_info() data:" + exp);
        }
        finally{
            if(null!=resultset)resultset.close();
            if(null != storedProcedure)storedProcedure.close();
            log.info("Stored procedure insert_user_info() ended**************");
        }
        return generatedUserId;
    } 

Follow the Reference for Java Code



来源:https://stackoverflow.com/questions/61813577/getting-psqlexception-while-calling-a-stored-procedure-which-inserts-record-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!