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

Oracle PL/SQL匿名块执行成功但数据未更新问题求助

问题原因

  • 第一,更新逻辑放置位置错误:你当前场景中刚好匹配到1条符合条件的行,SELECT INTO语句会正常执行不会触发任何异常,而你把更新操作写在了TOO_MANY_ROWS(匹配行数≥2)的异常分支里,正常匹配到1条数据的场景下没有任何更新/插入操作执行,当然不会修改holiday字段。
  • 第二,事务提交逻辑不全:你只在NO_DATA_FOUND的插入分支加了COMMIT,就算更新逻辑执行了,也没有提交事务,非自动提交模式下修改只会保存在当前会话的临时空间,不会持久化到数据库,关闭会话后变更会自动回滚。
  • 第三,更新语句条件不完整:原匹配条件包含emp_pk_id='32',但UPDATE语句的WHERE条件少了这个限制,后续逻辑修正后可能会误改其他同emp_id、同att_date但emp_pk_id不同的行。

修正后的PL/SQL块

DECLARE 
    c_emp_id att_log.emp_id%type;
BEGIN 
    SELECT emp_id
    INTO c_emp_id
    FROM att_log
    WHERE emp_id='19.1.0121'
      AND emp_pk_id='32'
      AND att_date='2021-10-01';
    
    -- 匹配到1条数据时执行更新,放到正常执行分支,不是异常分支
    UPDATE att_log
    SET holiday =  'H',
        updated_at = '2021-08-22'
    WHERE emp_id='19.1.0121'
      AND emp_pk_id='32' -- 补全匹配条件
      AND att_date='2021-10-01';
    COMMIT; -- 统一提交事务

EXCEPTION
    WHEN TOO_MANY_ROWS THEN
        -- 存在多条匹配数据的场景处理逻辑
        UPDATE att_log
        SET holiday =  'H',
            updated_at = '2021-08-22'
        WHERE emp_id='19.1.0121'
          AND emp_pk_id='32'
          AND att_date='2021-10-01';
        COMMIT;
    WHEN NO_DATA_FOUND THEN
        INSERT INTO att_log (emp_id, emp_pk_id, att_date, holiday,login_time, logout_time)
        VALUES ('19.1.0121', '32', '2021-10-01','H','','');
        COMMIT;
END;
/

更推荐的实现方案

Oracle原生提供MERGE语句专门处理这种「存在则更新、不存在则插入」的Upsert场景,逻辑更清晰,也不需要手动处理异常:

MERGE INTO att_log t
USING dual
ON (t.emp_id = '19.1.0121' AND t.emp_pk_id = '32' AND t.att_date = '2021-10-01')
WHEN MATCHED THEN
    UPDATE SET t.holiday = 'H', t.updated_at = '2021-08-22'
WHEN NOT MATCHED THEN
    INSERT (emp_id, emp_pk_id, att_date, holiday, login_time, logout_time)
    VALUES ('19.1.0121', '32', '2021-10-01', 'H', '', '');
COMMIT;
/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:24:05