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

Python oracledb调用Oracle存储过程无更新效果问题求助

问题排查与解决思路

1. 事务未提交(最可能的核心原因)

oracledb默认不会自动提交事务,即便存储过程执行成功,数据修改仅存在于当前会话的事务中,并未持久化到数据库。而SQL Developer通常会自动提交执行的语句,所以你复制生成的SQL到工具中能生效。

解决方法:
在调用存储过程的代码后添加事务提交操作:

# 调用存储过程后执行提交
connection.commit()

无论debug模式是否开启,都需要执行这一步。

2. 参数传递的隐形风险(推荐优化方向)

虽然你看到生成的SQL和SQL Developer一致,但手动拼接带引号的参数容易引发隐藏问题,同时存在SQL注入风险。建议重构存储过程使用绑定变量:

create or replace procedure update_reported_delta(
    update_tbl_name in varchar2,
    update_key_col in varchar2,
    update_key_vals in varchar2
)     
AUTHID CURRENT_USER
AS
    sql_cmd varchar(32767);
BEGIN
    sql_cmd:= 'UPDATE ' || update_tbl_name || '
        SET DELTA_REPORTED = ''Y''
        WHERE '|| update_key_col ||' in (:key_vals) AND DELTA_REPORTED IS NULL';
    execute immediate sql_cmd using update_key_vals;           
END;

Python调用时,参数直接传原值(无需额外加单引号):

params_list = ['my_tbl', 'my_id_col', 'MY_ID_VAL']

3. 会话权限与上下文验证

确认Python连接数据库的用户和SQL Developer使用的用户权限完全一致,包括是否激活了相同角色、是否存在行级安全策略(RLS)限制Python会话的更新操作。

可在Python中执行以下语句验证:

cursor.execute("SELECT USER FROM DUAL")
print(f"Current user: {cursor.fetchone()[0]}")

cursor.execute("SELECT PRIVILEGE FROM USER_SYS_PRIVS WHERE PRIVILEGE = 'UPDATE ANY TABLE'")
print(f"Update privilege: {cursor.fetchall()}")

4. 直接验证受影响行数

修改存储过程添加输出参数,查看实际更新的行数,排除数据本身不匹配的情况:

create or replace procedure update_reported_delta(
    update_tbl_name in varchar2,
    update_key_col in varchar2,
    update_key_vals in varchar2,
    out_affected_rows out number
)     
AUTHID CURRENT_USER
AS
    sql_cmd varchar(32767);
BEGIN
    sql_cmd:= 'UPDATE ' || update_tbl_name || '
        SET DELTA_REPORTED = ''Y''
        WHERE '|| update_key_col ||' in ('||update_key_vals||') AND DELTA_REPORTED IS NULL';
    execute immediate sql_cmd;
    out_affected_rows := SQL%ROWCOUNT;
    dbms_output.put_line('Affected rows: ' || out_affected_rows);
END;

Python调用时捕获输出参数:

params_list = ['my_tbl', 'my_id_col', "'MY_ID_VAL'", 0]
cursor.callproc(procedure_name, params_list)
print(f"Stored procedure affected rows: {params_list[3]}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:55:03