pyodbc调用DB2存储过程时提示全局变量RETC未找到的问题
解决DB2存储过程调用时全局变量未找到的问题
问题场景
通过Python的pyodbc调用IBM i上的DB2存储过程时,已执行全局变量创建语句,但调用存储过程时提示RETC变量未找到,具体报错:
('42S22', '[42S22] [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0206 - Column or global variable RETC not found. (-206) (SQLPrepare)')
关键代码片段:
crsr.execute("CREATE OR REPLACE VARIABLE AOMO DECIMAL DEFAULT 0.0") crsr.execute("CREATE OR REPLACE VARIABLE LSEQ DECIMAL DEFAULT 0.0") crsr.execute("CREATE OR REPLACE VARIABLE RETC CHAR") params = ('PB', event['orderNo'], '', '', '', '', 0,) crsr.execute("call MIE550EC.Z1NS910B(?,?,?,?,?,?,?,AOMO,LSEQ,RETC)", params)
解决方案
1. 修正全局变量的类型定义
DB2不允许创建无长度的CHAR类型全局变量,需指定明确长度,比如CHAR(10):
# 修正RETC变量的创建语句 crsr.execute("CREATE OR REPLACE VARIABLE RETC CHAR(10)")
2. 明确指定全局变量的模式
全局变量默认归属当前用户模式,若存储过程所在模式无法访问该变量,需在创建和调用时指定模式(例如存储过程所在的MIE550EC模式):
# 创建带模式的全局变量 crsr.execute("CREATE OR REPLACE VARIABLE MIE550EC.AOMO DECIMAL DEFAULT 0.0") crsr.execute("CREATE OR REPLACE VARIABLE MIE550EC.LSEQ DECIMAL DEFAULT 0.0") crsr.execute("CREATE OR REPLACE VARIABLE MIE550EC.RETC CHAR(10)") # 调用存储过程时指定模式 crsr.execute("call MIE550EC.Z1NS910B(?,?,?,?,?,?,?,MIE550EC.AOMO,MIE550EC.LSEQ,MIE550EC.RETC)", params)
3. 改用pyodbc输出参数绑定替代全局变量
全局变量易受会话、模式影响,直接使用pyodbc的输出参数绑定更可靠:
# 定义对应类型的输出参数 output_aomo = pyodbc.Decimal(0) output_lseq = pyodbc.Decimal(0) output_retc = pyodbc.Char(10) # 构造包含输出参数的参数列表 params = ( 'PB', event['orderNo'], '', '', '', '', 0, pyodbc.OutputParameter(output_aomo), pyodbc.OutputParameter(output_lseq), pyodbc.OutputParameter(output_retc) ) # 调用存储过程 crsr.execute("call MIE550EC.Z1NS910B(?,?,?,?,?,?,?,?,?,?)", params) # 获取输出参数值 print("AOMO:", output_aomo.value) print("LSEQ:", output_lseq.value) print("RETC:", output_retc.value)
4. 验证连接的库列表配置
连接字符串中dbq参数指定了访问的库列表,确保全局变量所在模式被包含其中:
# 修改dbq参数,加入变量所在模式 conn = pyodbc.connect(f"DSN=IBM i Access;SYSTEM={secret['ip']};PORT={secret['port']};DATABASE={secret['database']};UID={secret['username']};PWD={secret['password']};naming=1;dbq=MIE550EC,MAX550?????")
内容的提问来源于stack exchange,提问作者MitchE
相关产品推荐
相关产品推荐

