从 Java 方法(位于 DAO 层)调用存储过程(将记录插入 lsa_user_info table)时获取 PSQLException

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

我是存储过程的新手。我想在 lsa_user_info table 中插入一条包含 20 个列值的记录。我正在调用存储过程来完成此任务。

此外,我期望结果集将 return 插入记录的主键值 (user_id)。但是,我收到了这个错误:

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

lsa_user_info table 定义:

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;

这是我的存储过程:

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;

这是我调用存储过程的代码:

     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;
} 

请告诉我问题出在哪里?为什么我会收到此错误:

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

请帮助我!提前致谢

函数变化:在table中插入数据后,函数应该return插入行的user_id。你应该改变你的功能如下

  1. 将 return 类型从 Numeric 更改为 Bigint
  2. 更改参数名称,因为 table 列名称和参数名称相同。
  3. 使用 returning 语句 insert into 到 return 插入的 user_id

代码:

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;

JAVA 代码的变化:在Java 中,Postgres 函数的代码调用不同于MySQL 或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;
    } 

遵循 Reference Java 代码