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

使用oracledb向Oracle存储过程传递rowtype变量报错排查

问题:使用Python oracledb调用Oracle存储过程时出现TypeError

我有一个Oracle包ETL_RUN,其中包含如下声明的存储过程:

procedure pRunTask(pTask in out nocopy TASK_RUN%rowtype)

我尝试通过Python的oracledb库调用该存储过程,代码如下:

cursor.callproc('ETL_RUN.pRunTask', [task_run])

但出现如下错误:

File "...flows\migration_simple.py", line 48, in init
    cursor.callproc('ETL_RUN.pRunTask', keyword_parameters={'pTask': task_run})
  File "...venv\lib\site-packages\oracledb\cursor.py", line 651, in callproc
    self._call(name, parameters, keyword_parameters)
  File "...venv\lib\site-packages\oracledb\cursor.py", line 113, in _call
    return self.execute(statement, bind_values)
  File "...venv\lib\site-packages\oracledb\cursor.py", line 701, in execute
    impl.execute(self)
  File "src\\oracledb\\impl/thin/cursor.pyx", line 178, in oracledb.thin_impl.ThinCursorImpl.execute
  File "src\\oracledb\\impl/thin/protocol.pyx", line 437, in oracledb.thin_impl.Protocol._process_single_message
  File "src\\oracledb\\impl/thin/protocol.pyx", line 438, in oracledb.thin_impl.Protocol._process_single_message
  File "src\\oracledb\\impl/thin/protocol.pyx", line 399, in oracledb.thin_impl.Protocol._process_message
  File "src\\oracledb\\impl/thin/protocol.pyx", line 376, in oracledb.thin_impl.Protocol._process_message
  File "src\\oracledb\\impl/thin/messages.pyx", line 314, in oracledb.thin_impl.Message.send
  File "src\\oracledb\\impl/thin/messages.pyx", line 2162, in oracledb.thin_impl.ExecuteMessage._write_message
  File "src\\oracledb\\impl/thin/messages.pyx", line 2096, in oracledb.thin_impl.ExecuteMessage._write_execute_message
  File "src\\oracledb\\impl/thin/messages.pyx", line 428, in oracledb.thin_impl.MessageWithData._write_bind_params
  File "src\\oracledb\\impl/thin/messages.pyx", line 1115, in oracledb.thin_impl.MessageWithData._write_bind_params_row
  File "src\\oracledb\\impl/thin/messages.pyx", line 1081, in oracledb.thin_impl.MessageWithData._write_bind_params_column
  File "src\\oracledb\\impl/thin/packet.pyx", line 809, in oracledb.thin_impl.WriteBuffer.write_dbobject
TypeError: object of type 'NoneType' has no len()

其中task_run变量是从另一个Oracle函数获取的<oracledb.DbObject MAP.TASK_RUN%ROWTYPE at 0x152bec935e0>,请问哪里操作有误?


解决方案

  • 检查DbObject字段值:错误提示NoneType没有len(),说明task_run中的某个字符串类型字段(比如VARCHAR2)值为None。在oracledb thin模式下,绑定字符串类型的None会触发该错误,需确保所有字符串字段都赋值为空字符串''而非None。

  • 显式指定参数方向:由于存储过程参数是IN OUT NOCOPY类型,调用时需显式标记参数方向。示例代码:

import oracledb

# 初始化绑定参数,指定类型和方向
bind_param = cursor.var(oracledb.DB_OBJECT, typename="MAP.TASK_RUN", direction=oracledb.BIND_INOUT)
bind_param.setvalue(0, task_run)
cursor.callproc('ETL_RUN.pRunTask', [bind_param])
# 获取存储过程修改后的对象
updated_task_run = bind_param.getvalue()
  • 确认类型完全匹配:验证task_run的类型与存储过程要求的TASK_RUN%ROWTYPE完全一致,检查获取task_run的函数是否返回了完整的行类型对象,无字段缺失。

  • 切换到thick模式:若thin模式对复杂类型兼容性不足,可切换到thick模式(需安装Oracle客户端),执行以下代码启用:

oracledb.init_oracle_client()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:11:07