You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用含MERGE语句的Oracle存储过程时executeUpdate始终返回1求助

问题根因

你拿到的返回值永远为1的核心原因是 CallableStatement的executeUpdate()方法调用存储过程时,返回值仅表示存储过程是否执行成功,并非存储过程内部MERGE语句的实际影响行数。Oracle存储过程默认不会将内部DML的行数透传给JDBC接口,你当前拿到的1是存储过程执行成功的标识,和MERGE是否插入数据无关。

解决方案

第一步:修改存储过程,新增OUT参数返回影响行数

同时建议移除存储过程内部的COMMIT,事务控制交给上层Java代码更合理,避免事务边界混乱。

PROCEDURE INSERT_USER_PREFERENCES(
    owner_id_var varchar2, 
    stripeid_var varchar2, 
    type_var varchar2, 
    metadata_var CLOB,
    -- 新增OUT参数返回影响行数
    affect_rows OUT NUMBER
) AS
BEGIN
    MERGE INTO CXO_USER_PREFERENCES d
    USING(SELECT stripeid_var id FROM dual) s
    ON (d.stripe_id = s.id)
    WHEN NOT MATCHED THEN
        INSERT (OWNER_ID, STRIPE_ID, PREF_TYPE, METADATA, CREATED_DATE )
        VALUES(owner_id_var, stripeid_var, type_var, metadata_var, CURRENT_TIMESTAMP);
    -- 获取MERGE语句实际影响行数
    affect_rows := SQL%ROWCOUNT;
    -- 建议移除该行COMMIT,交由Java层控制事务
    -- COMMIT;
END  INSERT_USER_PREFERENCES;

第二步:修改Java调用逻辑,读取OUT参数值

不要使用executeUpdate()的返回值,改为读取存储过程返回的OUT参数即可拿到真实影响行数。

try (CallableStatement stmt = connection.prepareCall(CREATE_USER_PREF_SQL)) {
        SQLParameterMapper sqlParamMapper = new SQLParameterMapper(CREATE_USER_PREF_SQL);
        sqlParamMapper.setString(stmt, ":ownerId", userName);
        sqlParamMapper.setCharacterStream(stmt, ":metadata", reader, metadata.length());
        sqlParamMapper.setString(stmt, ":stripeId", stripeId);
        sqlParamMapper.setString(stmt, ":type", userPreference.getType());
        // 注册OUT参数,注意参数名和存储过程定义的OUT参数名对应
        stmt.registerOutParameter(":affect_rows", Types.NUMERIC);

        // 调用存储过程
        stmt.execute();
        // 读取真实影响行数
        int value = stmt.getInt(":affect_rows");
        return value;
    } catch (SQLException e) {
        // 存储过程执行出错会直接抛出异常,符合预期
        throw e;
    }

内容的提问来源于stack exchange,提问作者Harish Dalmia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:42:04